Skip to main content
  // ray tracing of the sphere
  // here we initialize the z-buffer's elements to -1.0 zBuffer that you find below
  ...

  //
  // rasterize a line
  //

  // line from p1 to p2 in LOCAL coordinates
  Point3d p1 (-1.0, 0.0, 0.0);
  Point3d p2 ( 1.0, 0.0, 0.0);

  // transformations...
    Matrix4d S  = Matrix4d::scaling (5.0, 1.0, 1.0);
    Matrix4d R1 = Matrix4d::rotation (0.5,'z');
    Matrix4d R2 = Matrix4d::rotation (tau,'x');
    Matrix4d T  = Matrix4d::translation (0.0, 0.0, 8.0);    

  Matrix4d M  = T*R2*R1*S;

  p1 = M*p1;
  p2 = M*p2;

  // screen coordinates
  double x1 = ( X + p1.x()/p1.z() ) / s - 0.5;
  double y1 = ( Y - p1.y()/p1.z() ) / s - 0.5;
  double x2 = ( X + p2.x()/p2.z() ) / s - 0.5;
  double y2 = ( Y - p2.y()/p2.z() ) / s - 0.5;

  //
  // line rasterization algorithm with anti-aliasing and z-test
  // (for lines with slope between -1 and 1)
  //
  int x  = round(x1);
  int y  = round(y1);

  double I0 = 1.0;
  double m = (y2-y1) / (x2-x1);

  bool up = true;
  if (y2 < y1) {
    m = -m;
    I0 = 0.0;
    up = false;
  }

  int nextY;
  double z;
  for ( ; x<=x2; x++) {
    if (up)
        nextY = y+1;
    else
        nextY = y-1;

    // barycentric coordinates of the current point: (1-lambda, lambda),
    // i.e.: x = (1-lambda) x1 + lambda x2
    double lambda = (x-x1) / (x2-x1);

    // perspectively correct linear interpolation of z-values
    z = p1.z()*p2.z() / ( (1.0-lambda)*p2.z() + lambda*p1.z() );

    if ( (zBuffer[x+y*w] < 0) || z < zBuffer[x+y*w] ) {
        int I = (int) 255*I0;
        image->setPixel( x, y,     qRgb( 255-I, 255, 255-I ) );
        image->setPixel( x, nextY, qRgb(     I, 255,     I ) );
    }

    if (m > I0) {
        y  = nextY;
        I0 += 1.0;
    }
    I0 -= m;
  }
 

  // repaint canvas
  repaint();
} 
  // ray tracing of the sphere
  // here we initialize the z-buffer's elements to -1.0 zBuffer that you find below
  ...

  //
  // rasterize a line
  //

  // line from p1 to p2 in LOCAL coordinates
  Point3d p1 (-1.0, 0.0, 0.0);
  Point3d p2 ( 1.0, 0.0, 0.0);

  // transformations...
    Matrix4d S  = Matrix4d::scaling (5.0, 1.0, 1.0);
    Matrix4d R1 = Matrix4d::rotation (0.5,'z');
    Matrix4d R2 = Matrix4d::rotation (tau,'x');
    Matrix4d T  = Matrix4d::translation (0.0, 0.0, 8.0);    

  Matrix4d M  = T*R2*R1*S;

  p1 = M*p1;
  p2 = M*p2;

  // screen coordinates
  double x1 = ( X + p1.x()/p1.z() ) / s - 0.5;
  double y1 = ( Y - p1.y()/p1.z() ) / s - 0.5;
  double x2 = ( X + p2.x()/p2.z() ) / s - 0.5;
  double y2 = ( Y - p2.y()/p2.z() ) / s - 0.5;

  //
  // line rasterization algorithm with anti-aliasing and z-test
  // (for lines with slope between -1 and 1)
  //
  int x  = round(x1);
  int y  = round(y1);

  double I0 = 1.0;
  double m = (y2-y1) / (x2-x1);

  bool up = true;
  if (y2 < y1) {
    m = -m;
    I0 = 0.0;
    up = false;
  }

  int nextY;
  double z;
  for ( ; x<=x2; x++) {
    if (up)
      nextY = y+1;
    else
      nextY = y-1;

    // barycentric coordinates of the current point: (1-lambda, lambda),
    // i.e.: x = (1-lambda) x1 + lambda x2
    double lambda = (x-x1) / (x2-x1);

    // perspectively correct linear interpolation of z-values
    z = p1.z()*p2.z() / ( (1.0-lambda)*p2.z() + lambda*p1.z() );

    if ( (zBuffer[x+y*w] < 0) || z < zBuffer[x+y*w] ) {
      int I = (int) 255*I0;
        image->setPixel( x, y,     qRgb( 255-I, 255, 255-I ) );
        image->setPixel( x, nextY, qRgb(     I, 255,     I ) );
    }

    if (m > I0) {
      y  = nextY;
      I0 += 1.0;
    }
    I0 -= m;
  }
 

  // repaint canvas
  repaint();
} 
// ray tracing of the sphere
// here we initialize the z-buffer's elements to -1.0 zBuffer that you find below
...

//
// rasterize a line
//

// line from p1 to p2 in LOCAL coordinates
Point3d p1 (-1.0, 0.0, 0.0);
Point3d p2 ( 1.0, 0.0, 0.0);

// transformations...
Matrix4d S  = Matrix4d::scaling (5.0, 1.0, 1.0);
Matrix4d R1 = Matrix4d::rotation (0.5,'z');
Matrix4d R2 = Matrix4d::rotation (tau,'x');
Matrix4d T  = Matrix4d::translation (0.0, 0.0, 8.0);

Matrix4d M  = T*R2*R1*S;

p1 = M*p1;
p2 = M*p2;

// screen coordinates
double x1 = ( X + p1.x()/p1.z() ) / s - 0.5;
double y1 = ( Y - p1.y()/p1.z() ) / s - 0.5;
double x2 = ( X + p2.x()/p2.z() ) / s - 0.5;
double y2 = ( Y - p2.y()/p2.z() ) / s - 0.5;

//
// line rasterization algorithm with anti-aliasing and z-test
// (for lines with slope between -1 and 1)
//
int x  = round(x1);
int y  = round(y1);

double I0 = 1.0;
double m = (y2-y1) / (x2-x1);

bool up = true;
if (y2 < y1) {
    m = -m;
    I0 = 0.0;
    up = false;
}

int nextY;
double z;
for ( ; x<=x2; x++) {
    if (up)
        nextY = y+1;
    else
        nextY = y-1;

    // barycentric coordinates of the current point: (1-lambda, lambda),
    // i.e.: x = (1-lambda) x1 + lambda x2
    double lambda = (x-x1) / (x2-x1);

    // perspectively correct linear interpolation of z-values
    z = p1.z()*p2.z() / ( (1.0-lambda)*p2.z() + lambda*p1.z() );

    if ( (zBuffer[x+y*w] < 0) || z < zBuffer[x+y*w] ) {
        int I = (int) 255*I0;
        image->setPixel( x, y,     qRgb( 255-I, 255, 255-I ) );
        image->setPixel( x, nextY, qRgb(     I, 255,     I ) );
    }

    if (m > I0) {
        y  = nextY;
        I0 += 1.0;
    }
    I0 -= m;
}

// repaint canvas
repaint();
added 928 characters in body
Source Link
user4718
user4718

Edit 2

After the corrections suggested by Nathan Reed, I obtained:

enter image description here

The colors of the pixels of the line over the sphere now really seem to be the product of the interpolation between the color green and the color of the sphere. Here's the code:

int I = (int)255 * I0;

Color3d background_color = pixels_colors[x + y * w];
Color3d green(0, 1.0, 0);

Color3d color_y = (1 - I0) * background_color + I0 * green;
Color3d color_next_y = I0 * background_color + (1 - I0) * green;

image->setPixel(x, nextY, qRgb(color_y.r() * 255, color_y.g() * 255, color_y.b() * 255));
image->setPixel(x, y, qRgb(color_next_y.r() * 255, color_next_y.g() * 255, color_next_y.b() * 255));

If this is now correct, the picture still doesn't look as it should. I think we may need to color more pixels?!


Edit 2

After the corrections suggested by Nathan Reed, I obtained:

enter image description here

The colors of the pixels of the line over the sphere now really seem to be the product of the interpolation between the color green and the color of the sphere. Here's the code:

int I = (int)255 * I0;

Color3d background_color = pixels_colors[x + y * w];
Color3d green(0, 1.0, 0);

Color3d color_y = (1 - I0) * background_color + I0 * green;
Color3d color_next_y = I0 * background_color + (1 - I0) * green;

image->setPixel(x, nextY, qRgb(color_y.r() * 255, color_y.g() * 255, color_y.b() * 255));
image->setPixel(x, y, qRgb(color_next_y.r() * 255, color_next_y.g() * 255, color_next_y.b() * 255));

If this is now correct, the picture still doesn't look as it should. I think we may need to color more pixels?!

added 414 characters in body
Source Link
user4718
user4718
 

Note (if you zoom in) that the line in the first picture is not that smooth over the sphere, because one of the pixels (at least) is colored for the background color white.


Edit

After trying to interpolate green and the current background color (as also Nathan Reed suggested), I obtained:

enter image description here

which is correct in the sense that I think that the interpolation is being done correctly, but at this point I think interpolation is not what we need to do to obtain a smooth line.

To obtain this I just added a few lines when setting the pixels of the line:

int I = (int)255 * I0;

Color3d c = pixels_colors[x + y * w]; 
// pixels_buffer contains the color at pixel x + y * w
// this color was saved while ray tracing the sphere

c.clamped();

int red = c.r() * 255;
int green = c.g() * 255;
int blue = c.b() * 255;

image->setPixel(x, y, qRgb(red - I, green, blue - I));
image->setPixel(x, y, qRgb(I, green, I));

Note (if you zoom in) that the line in the first picture is not that smooth over the sphere, because one of the pixels (at least) is colored for the background color white.

 

Note (if you zoom in) that the line in the first picture is not that smooth over the sphere, because one of the pixels (at least) is colored for the background color white.


Edit

After trying to interpolate green and the current background color (as also Nathan Reed suggested), I obtained:

enter image description here

which is correct in the sense that I think that the interpolation is being done correctly, but at this point I think interpolation is not what we need to do to obtain a smooth line.

To obtain this I just added a few lines when setting the pixels of the line:

int I = (int)255 * I0;

Color3d c = pixels_colors[x + y * w]; 
// pixels_buffer contains the color at pixel x + y * w
// this color was saved while ray tracing the sphere

c.clamped();

int red = c.r() * 255;
int green = c.g() * 255;
int blue = c.b() * 255;

image->setPixel(x, y, qRgb(red - I, green, blue - I));
image->setPixel(x, y, qRgb(I, green, I));
added 422 characters in body
Source Link
user4718
user4718
Loading
added 449 characters in body
Source Link
user4718
user4718
Loading
Source Link
user4718
user4718
Loading