Ir ao conteúdo
  • Cadastre-se

C++ Matemática: como se move 1 ponto no Espaço?


Cambalinho

Posts recomendados

eu estou a tentar mover a figura para a frente e para trás.... mas, algumas vezes, a figura se move para a direita ou esquerda..... algo está mal neste codigo:

void DrawLine3D(HDC Destination, int X0, int Y0, int Z0, int X1, int Y1, int Z1, COLORREF LineColor = RGB(255,0,0))
{
    //Avoiding division by zero:
    if(Z0==0) Z0=1;
    if(Z1==0) Z1=1;

    //Getting Line Distance(float results):
    float DX = X1 - X0;
    float DY = Y1 - Y0;
    float DZ = Z1 - Z0;
    float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2));


    //Getting the Steps incrementation(float results):
    float XSteps = DX/LineDistance;
    float YSteps = DY/LineDistance;
    float ZSteps = DZ/LineDistance;

    //Draw Line using the Steps\ Incrementation:
    float X = X0;
    float Y = Y0;
    float Z = Z0;
    int OldPosX=X0;
    int OldPosY=Y0;

    for(int i=0; i<LineDistance; i++)
    {
        //For every steps we calculate the perspective:
        float Perspective = 300/(300+Z);

        //The 3D to 2D convertion(i use 300 of eye distance, but we can change it):

        int PosX = trunc(X*Perspective);
        int PosY = trunc(Y*Perspective);
        //if(PosX==OldPosX && PosY==OldPosY) continue;
        OldPosX=PosX;
        OldPosY=PosY;

        //Draw the pixel:
        if(Z>0)
            SetPixel(Destination,PosX,PosY,LineColor);

        //Increment steps(integer results):
        X+=XSteps;
        Y+=YSteps;
        Z+=ZSteps;
    }
}
      //...............

int Front=0;
    int Speed=1;
    do
    {
        DrawLine3D(HDCConsole,100-Front,100,0-Front, 900-Front,100,500-Front);
        DrawLine3D(HDCConsole,100-Front,100,0-Front, 100-Front,400,0-Front);
        DrawLine3D(HDCConsole,900-Front,100,500-Front, 900-Front,400,500-Front);
        DrawLine3D(HDCConsole,100-Front,400,0-Front, 900-Front,400,500-Front);
        Sleep(50);
        FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0)));
        Speed=1;
        if((GetKeyState(VK_RSHIFT) & 0x8000))
        {
            Speed=10;
        }

        if((GetKeyState(VK_UP) & 0x8000))
        {
            Front+=Speed;
        }
        if((GetKeyState(VK_DOWN) & 0x8000))
        {
            Front-=Speed;
        }

    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));

sim em algumas coordenadas a figura se move para a direita e não, só, para a frente e para trás 😞

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho     para quê o zero ?   ,  somar com zero não modifica nada  ,  e se quer mover um ponto no eixo Z das coordenadas cartesianas ,  basta somar para o ponto se mover para baixo e subtrair para que o ponto se mova para cima  .

ex.:

ex.:
p = 50,40,5;           /// ponto inicial
p = 50 , 40 , 5 + 1;   /// mover um ponto para baixo
p = 50 , 40 , 5 - 3;   /// mover três ponto para cima

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

isso era simples, mas não funciona.. tive de criar estas funções:

void LineMoveFront(int &X0, int &Y0, int &Z0,int &X1, int &Y1, int &Z1, int Speed)
{
    float DX = X1 - X0;
    float DY = Y1 - Y0;
    float DZ = Z1 - Z0;
    float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2));
    float XStep = DX / LineDistance;
    float YStep = DY / LineDistance;
    float ZStep = DZ / LineDistance;
    X0+=round(XStep*Speed);
    Y0+=round(YStep*Speed);
    Z0+=round(ZStep*Speed);

    X1+=round(XStep*Speed);
    Y1+=round(YStep*Speed);
    Z1+=round(ZStep*Speed);
}

void LineMoveBack(int &X0, int &Y0, int &Z0,int &X1, int &Y1, int &Z1, int Speed=1)
{
    float DX = X1 - X0;
    float DY = Y1 - Y0;
    float DZ = Z1 - Z0;
    float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2));
    float XStep = DX / LineDistance;
    float YStep = DY / LineDistance;
    float ZStep = DZ / LineDistance;
    X0-=round(XStep*Speed);
    Y0-=round(YStep*Speed);
    Z0-=round(ZStep*Speed);

    X1-=round(XStep*Speed);
    Y1-=round(YStep*Speed);
    Z1-=round(ZStep*Speed);
}


int main()
{
    HDC HDCConsole = GetConsoleHDC();

    RECT rec;
    GetClientRect(GetConsoleWindow(),&rec);

    int Speed=1;
    int LinePositions[6] = {100,100,0,900,100,500};


    do
    {
        DrawLine3D(HDCConsole,LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5]);
        Sleep(50);
        FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0)));
        Speed=1;
        if((GetKeyState(VK_RSHIFT) & 0x8000))
        {
            Speed=10;
        }

        if((GetKeyState(VK_UP) & 0x8000))
        {
            LineMoveBack(LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5], Speed);
        }
        if((GetKeyState(VK_DOWN) & 0x8000))
        {
            LineMoveFront(LinePositions[0],LinePositions[1], LinePositions[2], LinePositions[3], LinePositions[4], LinePositions[5], Speed);
        }

    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));
    cout << "Draw ended!!!";
    cin.get();
    return 0;
}

é mais complexo mas faz o que queria... a linha se move com a mesma direção\angulo

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

desculpa, mas não entendi.

- DrawLine3D() desenha a linha com Z;

- LineMoveBack() e LineMoveFront() usa Z e é para mover a linha para a frente e para trás.

 

desculpem perguntar fora do tópico: mas o que devo ter em atenção para aumentar a velocidade da função?

claro que o SetPixel() é lento

 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@Cambalinho    é que você não postou essa função  ,    e sim , o SetPixel plota um pixel por vez , assim demora muito mesmo ,  e você já tentou usar uma função nativa da linguagem c++ , para desenhar Linhas   ? ,   " MoveToEx "  e  " LineTo " ,, ,

MoveToEx(tela,  static_cast<int>(sin(i*3.141615/180)*100+700),
static_cast<int>(cos(i*3.141615/180)*100+250),NULL) ;                  ///  posição de inicio
for( j=1; j<4; j++ )
  LineTo( tela                                                      ,
          static_cast<int>(sin((i+ j*120+00)*3.141615/180)*100+700) ,
          static_cast<int>(cos((i+ j*120+00)*3.141615/180)*100+250));  ///  vai para essas posições

 

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

eu tenho essa função por 2 razões:
1 - aprender a desenhar linhas em programação, usando Matemática;
2 - aprender a fazer a mesma função para 3D.

mais tarde vou aprender a fazer círculos e depois curvas 😉
no #5 está a função DrawLine3D() 😉
eu gostava de aprender mais sobre otimização e velocidade nas funções.. se souber alguma coisa ou link por favor partilhe
 

  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

  • mês depois...
  • 2 meses depois...

@Cambalinho      para ter maior velocidade , você pode  organizar seu código de forma  que não use esse "Sleep"  , pois isso faz demorar muito ,   

#define    _WIN32_WINNT 0x600
#include   <stdio.h>
#include   <conio.h>
#include   <windows.h>
#include   <string.h>
#include   <math.h>
#include   <iostream>
/*   site
  https://www.clubedohardware.com.br/forums/topic/1619190-matem%C3%A1tica-como-se-move-1-ponto-no-espa%C3%A7o/#comment-8483220
  
  coloque isso no link do compilador
  -lgdi32
  -lmingw32
  -lopengl32
  -lopengl32
  -lwinmm
  no codeblocks  Settings / Compiler / Linker Settings / Other Linker Options
*/
using namespace std;
int flg = 1;
void LineMove(int &X0, int &Y0, int &Z0,int &X1, int &Y1, int &Z1,int Speed=1)
{
  float DX = X1 - X0;
  float DY = Y1 - Y0;
  float DZ = Z1 - Z0;
  float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2));
  float XStep = DX / LineDistance;
  float YStep = DY / LineDistance;
  float ZStep = DZ / LineDistance;
  if( flg == 2 )
  {
    X0 += round( XStep * Speed );
    Y0 += round( YStep * Speed );
    Z0 += round( ZStep * Speed ); /// LineMoveFront
    X1 += round( XStep * Speed );
    Y1 += round( YStep * Speed );
    Z1 += round( ZStep * Speed );
  }
  else
  {
    X0 -= round( XStep * Speed );
    Y0 -= round( YStep * Speed );
    Z0 -= round( ZStep * Speed );
    X1 -= round( XStep * Speed ); /// LineMoveBack
    Y1 -= round( YStep * Speed );
    Z1 -= round( ZStep * Speed );
  }
}
void DrawLine3D(HDC Destination, int X0, int Y0, int Z0, int X1, int Y1, int Z1,COLORREF LineColor )
{
  //Avoiding division by zero:
  if(Z0==0) Z0=1;
  if(Z1==0) Z1=1;

  //Getting Line Distance(float results):
  float DX = X1 - X0;
  float DY = Y1 - Y0;
  float DZ = Z1 - Z0;
  float LineDistance = sqrt(pow(DX,2) + pow(DY,2) + pow(DZ,2));

  //Getting the Steps incrementation(float results):
  float XSteps = DX/LineDistance;
  float YSteps = DY/LineDistance;
  float ZSteps = DZ/LineDistance;

  //Draw Line using the Steps\ Incrementation:
  float X     = X0;
  float Y     = Y0;
  float Z     = Z0;
  int OldPosX = X0;
  int OldPosY = Y0;

  for( int i=0; i<LineDistance; i++ )
  {
    //For every steps we calculate the perspective:
    float Perspective = 300/(300+Z);

    //The 3D to 2D convertion(i use 300 of eye distance, but we can change it):

    int PosX = trunc( X * Perspective );
    int PosY = trunc( Y * Perspective );
    OldPosX  = PosX;
    OldPosY  = PosY;

    //Draw the pixel:
    if( Z>0 )
      SetPixel(Destination,PosX,PosY,LineColor);

    //Increment steps(integer results):
    X+=XSteps;
    Y+=YSteps;
    Z+=ZSteps;
  }
}

int main()
{
  HDC HDCConsole;
  HWND     csl                          ;
  RECT rec                              ;
  GetClientRect(GetConsoleWindow(),&rec);
  csl         = GetConsoleWindow(      );
  HDCConsole  = GetDC(  csl            );
  int Speed   = 1                       ;
  int Front   = 0                       ;
  int LinePositions[6] = {100,100,0,900,100,500};
  COLORREF LineColor   = RGB( 255, 255, 0    );
  do
  {
    if(flg)
    {
      flg = 0;
      FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0)));
      DrawLine3D( HDCConsole, 100 - Front, 100, 0 - Front,
                  900 - Front, 100, 500 - Front,LineColor );
      DrawLine3D( HDCConsole, 100 - Front, 100, 0 - Front,
                  100 - Front, 400, 0   - Front, LineColor );
      DrawLine3D( HDCConsole, 900 - Front, 100, 500-Front,
                  900 - Front, 400, 500 - Front,LineColor );
      DrawLine3D( HDCConsole, 100 - Front, 400, 0 - Front,
                  900 - Front, 400, 500 - Front,LineColor );
    }
    Speed=1;
    if((GetKeyState(VK_RSHIFT) & 0x8000))
      Speed=10;
    if((GetKeyState(VK_UP) & 0x8000))
    {
      Front += Speed;
      flg = 1;
    }
    if((GetKeyState(VK_DOWN) & 0x8000))
    {
      Front -= Speed;
      flg = 1;
    }
  }
  while(!(GetKeyState(VK_ESCAPE) & 0x8000));
  printf("     Tecle Enter");
  cin.get(); /// pede teclar enter
  flg = 1;
  do
  {
    if( flg )  /// se moveu a linha
    {
      LineMove
      (
          LinePositions[0],LinePositions[1], LinePositions[2],
          LinePositions[3],LinePositions[4], LinePositions[5],
          Speed
      );       /// calcula a prOxima posiCAo da linha
      flg = 0; /// reseta a flag
      FillRect(HDCConsole,&rec,CreateSolidBrush(RGB(0,0,0))); /// limpa a tela
      DrawLine3D(HDCConsole,   /// desenha a linha na nova posiCAo
                 LinePositions[0],LinePositions[1],
                 LinePositions[2],LinePositions[3],
                 LinePositions[4],LinePositions[5],
                 LineColor );  /// com essa cor
    }
    Speed=1;
    if((GetKeyState(VK_RSHIFT) & 0x8000)) /// se pressionou Shift Direito
      Speed = 10;                         /// velocidade 10
    if((GetKeyState(VK_UP) & 0x8000))     /// se pressionou Seta para Cima
      flg = 1;                            /// flag recebe valor 1
    if((GetKeyState(VK_DOWN) & 0x8000))   /// se pressionou Seta para Baixo
      flg = 2;                            /// flag recebe valor 2
  }
  while(!(GetKeyState(VK_ESCAPE) & 0x8000));

  cout << "Draw ended!!!";
  cin.get(); /// pede teclar enter
  return 0;
}

 

  • Amei 1
Link para o comentário
Compartilhar em outros sites

  • 3 semanas depois...

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

Ebook grátis: Aprenda a ler resistores e capacitores!

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!