i'm trying update a DrawLine3D(), but how use max()?

from http://members.chello.at/easyfilter/bresenham.html
i'm trying draw a 3D Line:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void plotLine3d(int x0, int y0, int z0, int x1, int y1, int z1)
{
   int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
   int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1; 
   int dz = abs(z1-z0), sz = z0<z1 ? 1 : -1; 
   int dm = max(dx,dy,dz), i = dm; /* maximum difference */
   x1 = y1 = z1 = dm/2; /* error offset */
 
   for(;;) {  /* loop */
      setPixel(x0,y0,z0);
      if (i-- == 0) break;
      x1 -= dx; if (x1 < 0) { x1 += dm; x0 += sx; } 
      y1 -= dy; if (y1 < 0) { y1 += dm; y0 += sy; } 
      z1 -= dz; if (z1 < 0) { z1 += dm; z0 += sz; } 
   }
}

ok the:
setPixel(x0,y0,z0); is wrong, but, on these case, we can do:
SetPixel(HDCDestination,x0,y0);
the z0 is ignored, because we must do the perspective 1st.
but, for now, let fix these line:
int dm = max(dx,dy,dz), i = dm; /* maximum difference */
compiler error message:
"'__comp' cannot be used as a function"
so what is wrong with these line?
ok.. i never used the max()... so i don't know how can use it.
so what is wrong with my own function!?! some pixels, depending on rotation, i can lose some :(
The third parameter to std::max() is a comparison function. To get the maximum of three values you can do std::max(x, std::max(y, z)).
if i use another parameter i must do:
std::max(x, std::max(y, std::max(z,v)))
right?
Yes, that works.
You can also do std::max( { x, y, z } );
thank you to all.
now lets see the next problems:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void plotLine3d(HDC HDCDestination, int x0, int y0, int z0, int x1, int y1, int z1)
{
   int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
   int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
   int dz = abs(z1-z0), sz = z0<z1 ? 1 : -1;
   int dm =std::max(dx, std::max(dy, dz)), i = dm; /* maximum difference */
   x1 = y1 = z1 = dm/2; /* error offset */

   //i is 100 on these test

   for(;;) {  /* loop */
        //std::cout << "\t" << i;
      SetPixel(HDCDestination,x0,y0,RGB(255,0,0));
      if (i-- == 0) break;
      x1 -= dx; if (x1 < 0) { x1 += dm; x0 += sx; }
      y1 -= dy; if (y1 < 0) { y1 += dm; y0 += sy; }
      z1 -= dz; if (z1 < 0) { z1 += dm; z0 += sz; }
   }
}

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());


    plotLine3d(WindowHDC,0,0,0,100,0,0);

    return 0;
}

1
2
 for(;;) {  /* loop */
        //std::cout << "\t" << i; 

- if i don't use the cout, the line isn't printed;
- if i use the cout, line is printed, but don't start on position zero...
why these 2 problems?
Last edited on
Did you mean to do this?
1
2
3
   while(i--) {  /* loop */
        std::cout << "\t" << i;
      SetPixel(HDCDestination,x0,y0,RGB(255,0,0));
Last edited on
do me a favor and test the last code and see what i mean.
ok... i didn't showed the '#include' files, but test the code please
now works.. but i did a loop for draw the line(if not we can't see the line):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void plotLine3d(HDC HDCDestination, int x0, int y0, int z0, int x1, int y1, int z1)
{
   int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
   int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
   int dz = abs(z1-z0), sz = z0<z1 ? 1 : -1;
   int dm =std::max( { dx, dy, dz } ), i = dm; /* maximum difference */
   x1 = y1 = z1 = dm/2; /* error offset */

   //i is 100 on these test
    //std::cout << i;
   do
    {  /* loop */
        //std:: cout << "\they";

      x1 -= dx; if (x1 < 0) { x1 += dm; x0 += sx; }
      y1 -= dy; if (y1 < 0) { y1 += dm; y0 += sy; }
      z1 -= dz; if (z1 < 0) { z1 += dm; z0 += sz; }
      SetPixel(HDCDestination,x0,y0,RGB(255,0,0));
        i--;

   }while(i >= 0);
}

int main()
{

     //getting the HDC Console Window:
    HDC WindowHDC=GetDC(GetConsoleWindow());

    do
    {
       plotLine3d(WindowHDC,0,0,0,100,0,0);
    }while(!(GetKeyState(VK_ESCAPE) & 0x8000));

    cout<<"Press return to end . . ."<<endl;
    cin.get();
    return 0;
}

now i will teste the rotation and a filled rectangle.... thanks for all
instead use 'SetPixel()' i can use the 'x0', 'y0' and 'z0' for get the line dots... thanks for all
Hm...
1
2
3
4
do{
    print(i);
    i--;
}while (i >= 0);
is equivalent to
1
2
3
do{
    print(i);
}while (--i >= 0);
so that means that just before the while condition, if i == 0 then the loop is about to end. If the initial value of i is 100, the output of this program would be 100 99 98 ... 2 1 0; and if it is 0 it will be 0. Are you sure that's what you want?

For comparison, the output of this program
1
2
while (i--)
    print(i);

is 99 98 ... 2 1 0 for an initial value of 100, and no output for an initial value of 0.
Honestly you have right. It's starting on 100 instead zero. So can I convert the code or, after save the points line, I must sort the values?
tested.. the 'i' starts on last, but the position line starts on origin:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
void plotLine3d(HDC HDCDestination, int x0, int y0, int z0, int x1, int y1, int z1)
{
    int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
    int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
    int dz = abs(z1-z0), sz = z0<z1 ? 1 : -1;
    int dm =std::max( { dx, dy, dz } ), i = dm; /* maximum difference */
    x1 = y1 = z1 = dm/2; /* error offset */
    bool First=false;
    do
    {
        x1 -= dx; if (x1 < 0) { x1 += dm; x0 += sx; }
        y1 -= dy; if (y1 < 0) { y1 += dm; y0 += sy; }
        z1 -= dz; if (z1 < 0) { z1 += dm; z0 += sz; }
        if(First==false)
        {
            SetPixel(HDCDestination,x0,y0,RGB(0,0,255));
            First=true;
        }
        else
        {
            SetPixel(HDCDestination,x0,y0,RGB(255,0,0));
        }


        i--;

    }while(i >= 0);
}

heres now my last update:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
struct point
{
    float x,y,z;
} ;

vector<point> GetLinePoints(int x0, int y0, int z0, int x1, int y1, int z1)
{
    vector<point> LinePoints;
    point LinePoint;
    int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
    int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
    int dz = abs(z1-z0), sz = z0<z1 ? 1 : -1;
    int dm =std::max( { dx, dy, dz } ), i = dm; /* maximum difference */
    x1 = y1 = z1 = dm/2; /* error offset */

    do
    {
        x1 -= dx; if (x1 < 0) { x1 += dm; x0 += sx; }
        y1 -= dy; if (y1 < 0) { y1 += dm; y0 += sy; }
        z1 -= dz; if (z1 < 0) { z1 += dm; z0 += sz; }
        LinePoint.x=x0;
        LinePoint.y=y0;
        LinePoint.z=z0;
        LinePoints.push_back(LinePoint);
        i--;
    }while(i >=0);
    return LinePoints;
}

void DrawLine3D(HDC HDCDestination, int x0, int y0, int z0, int x1, int y1, int z1, COLORREF color=RGB(255,255,255), int lenght=1)
{
    //Get Line Dots Positions:
    vector <point> LinePoints=GetLinePoints(x0,y0,z0,x1,y1,z1);
    
    //Draw the Line Dots Positions:
    for(int LinePosition=0; LinePosition<LinePoints.size(); LinePosition++)
    {
        //Draw Line Lenght:
        for(int LineLenght=0;LineLenght<lenght; LineLenght++)
        {
            SetPixel(HDCDestination,LinePoints[LinePosition].x,LinePoints[LinePosition+LineLenght].y,color);
        }
    }
}

'LineLenght' is for a horizontal line, thats why use the 'y'. the vertical line use the 'x'.
i use 'SetPixel()', but we can use the pixels pointer(like DIB's). PS: we can't get the Window HBITMAP, but we can use a memory HDC with HBITMAP and then draw on it the result. and the BitBlt() draw the result on Window HDC.(don't forget use a loop for draw something or use the Paint() event.
thanks for all
Last edited on
using these function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
vector<point> GetLinePoints(point Origin, point Destination)
{
    vector<point> LinePoints;
    point LinePoint;
    int dx = abs(Destination.x-Origin.x), sx = Origin.x<Destination.x ? 1 : -1;
    int dy = abs(Destination.y-Origin.y), sy = Origin.y<Destination.y ? 1 : -1;
    int dz = abs(Destination.z-Origin.z), sz = Origin.z<Destination.z ? 1 : -1;
    int dm =std::max( { dx, dy, dz } ), i = dm; /* maximum difference */
    Destination.x = Destination.y = Destination.z = dm/2; /* error offset */

    do
    {
        Destination.x -= dx; if (Destination.x < 0) { Destination.x += dm; Origin.x += sx; }
        Destination.y -= dy; if (Destination.y < 0) { Destination.y += dm; Origin.y += sy; }
        Destination.z -= dz; if (Destination.z < 0) { Destination.z += dm; Origin.z += sz; }
        LinePoint.x=Origin.x;
        LinePoint.y=Origin.y;
        LinePoint.z=Origin.z;
        LinePoints.push_back(LinePoint);
        i--;
    }while(i >=0);
    return LinePoints;
}

i can lose some pixels.. please see the image.
https://imgur.com/EUTvfcP
i don't know nothing about that error. but i have seen that error before.
that error have to do with 'Anti-aliased'?
Last edited on
Topic archived. No new replies allowed.