Ir ao conteúdo

Posts recomendados

Postado

eis a minha função atual para desenhar 1 linha com 1 comprimento e Radianos:

void DrawLineAngle(int X0, int Y0, float Radians, int Width)//Width é 100
{
    int X1 = X0 + cos(Radians)*Width;//200
    int Y1 = Y0 + sin(Radians)*Width;
    cout << "X1: " << X1<< "\n";
    int dx = abs(X1-X0);
    int dy = abs(Y1-Y0);
    double Steps;
    double x=X0;
    double y=Y0;
    HDC HDCConsole = GetWindowDC(GetConsoleWindow());
    HPEN LineColor = CreatePen(0,1,RGB(255,0,0));
    HPEN OldPen =(HPEN)SelectObject(HDCConsole,LineColor);

    const double INCREMENTO = 32.0;
    if (dx >dy)
        Steps = dx;
    else
        Steps = dy;
    double Xincrement = (dx / Steps) * INCREMENTO;
    double Yincrement = (dy / Steps) * INCREMENTO;
    cout << "Xincrement: " << Xincrement<< "\n";
    int v=0;
    for(v=0; v < Steps; v++)
    {
        x = x + Xincrement;
        y = y + Yincrement;
        cout << "X: " << x  << "  Y: " << y << "\n";
        if(x>=X1 or y>=Y1) break;//porque tenho de usar esse 'if', senão dá-me mais comprimento
    }

    cout << v<< "\n";
    MoveToEx(HDCConsole,X0,Y0,nullptr);
    LineTo(HDCConsole,X0+100,y);
    SelectObject(HDCConsole,OldPen);
    DeleteObject(LineColor);
}

e como a uso:

DrawLineAngle(100,100,0,100);

porque o ciclo 'for' é executado 1 única vez e o 'v' é zero?
deveria somar '32' no 'x' e 1 vez seria '132', ou seja inferior ao comprimento.... o que estou a fazer errado no código?

  • Curtir 1
Postado
Em 17/11/2023 às 14:54, Cambalinho disse:

porque o ciclo 'for' é executado 1 única vez e o 'v' é zero?

 

Bom, por que foi exatamente isso que você pediu pro programa executar. Ou seja, se Y0 + 0 for maior ou igual a Y0, o que é verdade (y=Y0 e Y1=Y0 se Radians=0), então o loop deve ser terminado.

 

Em 17/11/2023 às 14:54, Cambalinho disse:

deveria somar '32' no 'x' e 1 vez seria '132', ou seja inferior ao comprimento....

 

32 + 100 parece-me suficientemente maior que 100, supondo que você se refere a width como um comprimento.

 

Em 17/11/2023 às 14:54, Cambalinho disse:

o que estou a fazer errado no código?

 

Off-topic: Aparentemente, muitas coisas, mas o mais importante seria ter um pouco mais de cuidado na hora das operações aritméticas misturando int, float e double. Sempre converta tudo pra float ou double, dependendo do nível de precisão que deseja, antes das operações. O compilador tá realizando várias conversões implícitas e o código executado não é exatamente o código escrito. Portanto, ele é péssimo pra ler, pra debugar e provavelmente vai ter erros durante o runtime também.

  • Curtir 1
  • Amei 1
Postado

tem razão amigo... por isso alterei o código:

void DrawLineAngle(int X0, int Y0, float Radians, int Width)
{
    int X1 = X0 + cos(Radians)*Width;
    int Y1 = Y0 + sin(Radians)*Width;
    int dx = abs(X1-X0);
    int dy = abs(Y1-Y0);
    double Steps;
    double x=X0;
    double y=Y0;
    HDC HDCConsole = GetWindowDC(GetConsoleWindow());
    HPEN LineColor = CreatePen(0,1,RGB(255,0,0));
    HPEN OldPen =(HPEN)SelectObject(HDCConsole,LineColor);

    const double INCREMENTO = 32.0;
    if (dx >dy)
        Steps = dx;
    else
        Steps = dy;
    double Xincrement = (dx / Steps) * INCREMENTO;
    double Yincrement = (dy / Steps) * INCREMENTO;
    int v=0;

    while(x<=X1 and y<=Y1)
    {
        x = x + Xincrement;
        y = y + Yincrement;
        v++;
    };
    if(x>X1) x=X1;
    if(y>Y1) y=Y1;
    cout << "Steps: " << v << "\n";
    MoveToEx(HDCConsole,X0,Y0,nullptr);
    LineTo(HDCConsole,x,y);
    SelectObject(HDCConsole,OldPen);
    DeleteObject(LineColor);
}

agora funciona 😉

muito obrigado.

esta função pode ser usada ou atualizada para usar numa grelha com quadrados de 32 por 32?(mesmo que só passe 3 ou 4 pixels no mesmo quadrado)

  • Curtir 1
Postado
56 minutos atrás, Cambalinho disse:

esta função pode ser usada ou atualizada para usar numa grelha com quadrados de 32 por 32?

 

Aparentemente, ela independe da extensão da superfície (dentro de HDCConsole suponho?).

  • Curtir 1
Postado

sim... estou a tentar:

void DrawRayLine(int X0, int Y0, float Radians, int Width,int Walls[10][10], int WallWidth, int WallHeight)
{
    int X1 = X0 + static_cast<int>(cos(Radians) * Width);
    int Y1 = Y0 + static_cast<int>(sin(Radians) * Width);

    int dx = abs(X1 - X0);
    int dy = abs(Y1 - Y0);

    double Steps;
    double x = X0;
    double y = Y0;

    // Calcular incrementos
    double INCREMENTO = 32.0;
    double Xincrement = INCREMENTO * cos(Radians);
    double Yincrement = INCREMENTO * sin(Radians);

    // Restante do código para desenhar o raio

    // Verificar se toca em uma parede

    bool hitsWall = false;
    while (x < X1 || y < Y1)
    {
         int currentX = static_cast<int>(x /32);
        int currentY = static_cast<int>(y /32);
        //cout << x << "\t" << y <<"\n";
        if (currentX >= 0 && currentX < WallWidth && currentY >= 0 && currentY < WallHeight)
        {
            if (Walls[currentX][currentY] != 0)
            {
                hitsWall = true;
                break;
            }
        }

        x += Xincrement;
        y += Yincrement;
    }
    HDC HDCConsole = GetWindowDC(GetConsoleWindow());
    HPEN LineColor = CreatePen(0,1,RGB(255,0,0));
    HPEN OldPen =(HPEN)SelectObject(HDCConsole,LineColor);
    MoveToEx(HDCConsole,X0,Y0,nullptr);
    LineTo(HDCConsole,x,y);
    SelectObject(HDCConsole,OldPen);
    DeleteObject(LineColor);
}

int main()
{
    int LevelMap[10][10]=
    {
        {1,1,1,1,1,1,1,1,1,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,1,1,1,1,1,1,1,1,1}
    };

    for(int X=0, Y=0;Y<10;)
    {
        HDC HDCConsole = GetWindowDC(GetConsoleWindow());
        Rectangle(HDCConsole,X*32,Y*32,X*32+31,Y*32+31);// ainda não comparo os valores para mudar a cor
        X++;
        if(X>=10)
        {
            X=0;
            Y++;
        }
    }
    DrawRayLine(3*32,3*32,25*3.14/180,200,LevelMap,10,10);
    cin.get();
    return 0;
}

este exemplo desenha a linha desejada, mas a linha termina no interior do quadrado e não no inicio do quadrado.... por usar o 32. e isso pode variar com o angulo.

  • Curtir 1
Postado

consegui melhores resultados:

double GetRadians(int Degrees)
{
    return (Degrees*M_PI/180);
}

void DrawRayLine(double X0, double Y0, double Radians, int Width,int Walls[10][10], int WallWidth, int WallHeight)
{
    double adjustedRadians = fmod(Radians, 2 * M_PI);

    double X1 = X0 + cos(adjustedRadians) * Width;
    double Y1 = Y0 + sin(adjustedRadians) * Width;

    if (X1 < X0)
    {
        double temp = X0;
        X0 = X1;
        X1 = temp;
    }

    double dx = abs(X1 - X0);
    double dy = abs(Y1 - Y0);

    double Steps;
    double x = X0;
    double y = Y0;
     if (dx >dy)
        Steps = dx;
    else
        Steps = dy;
    // Calcular incrementos
    double INCREMENTO = 5.0;
    double Xincrement =  (dx / Steps) * INCREMENTO;
    double Yincrement =  (dy / Steps) * INCREMENTO;

    // Restante do código para desenhar o raio

    // Verificar se toca em uma parede

    bool hitsWall = false;
    int S=0;
    while (x < X1 || y < Y1)
    {
        int currentX = static_cast<int>(x /32);
        int currentY = static_cast<int>(y /32);
        //cout << x << "\t" << y <<"\n";
        if (currentX >= 0 && currentX < WallWidth && currentY >= 0 && currentY < WallHeight)
        {
            if (Walls[currentY][currentX] != 0)
            {
                hitsWall = true;
                break;
            }
        }

        x += Xincrement;
        y += Yincrement;
        S++;
    }
    MessageBox (NULL,to_string(S).c_str(), "hello",MB_OK);
    HDC HDCConsole = GetWindowDC(GetConsoleWindow());
    HPEN LineColor = CreatePen(0,1,RGB(255,0,0));
    HPEN OldPen =(HPEN)SelectObject(HDCConsole,LineColor);
    MoveToEx(HDCConsole,X0,Y0,nullptr);
    LineTo(HDCConsole,x,y);
    SelectObject(HDCConsole,OldPen);
    DeleteObject(LineColor);
}

HDC HDCConsole = GetWindowDC(GetConsoleWindow());

int main()
{
    int LevelMap[10][10]=
    {
        {1,1,1,1,1,1,1,1,1,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,1,0,0,1},
        {1,0,0,0,0,1,0,0,0,1},
        {1,0,0,0,0,0,1,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,0,0,0,0,0,0,0,0,1},
        {1,1,1,1,1,1,1,1,1,1}
    };
    HBRUSH WhiteSquare=CreateSolidBrush(RGB(255,255,255));
    HBRUSH BlueSquare=CreateSolidBrush(RGB(0,0,255));
    HBRUSH OldBrush;
    for(int X=0, Y=0;Y<10;)
    {

        if(LevelMap[Y][X]==1) OldBrush=(HBRUSH)SelectObject(HDCConsole,BlueSquare);
        if(LevelMap[Y][X]!=1) OldBrush=(HBRUSH)SelectObject(HDCConsole,WhiteSquare);
        Rectangle(HDCConsole,X*32,Y*32,X*32+35,Y*32+35);
        X++;
        if(X>=10)
        {
            X=0;
            Y++;
        }
        SelectObject(HDCConsole,OldBrush);
    }
    DeleteObject(WhiteSquare);
    DeleteObject(BlueSquare);
    DrawRayLine(3.5*32,3.5*32,GetRadians(45),10000,LevelMap,10,10);
    cin.get();
    return 0;
}

noto 1 problema: se 45º é anti-horario porquê este resultado da linha vermelha?
image.thumb.png.22c883215a558b57b3e6e956064de5c1.png

  • Curtir 1

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...

LANÇAMENTO!

eletronica2025-popup.jpg


CLIQUE AQUI E BAIXE AGORA MESMO!