Why does the rendered line break when it is vertical —— lesson 1
Drincann opened this issue · comments
In Second attempt - lesson 1, the expession used to calculate y changes as follows:
// first
int y = y0 + (y1-y0)*t;
// second
int y = y0*(1.-t) + y1*t;
Using the expression used in the second attempt, I found an exception when drawing a line with no slope (vertical). This line jitters back and forth within two pixels in the x direction like:
impl:
void CanvasContext::line(const Point& start, const Point& end) {
int x0 = start.x, x1 = end.x, y0 = start.y, y1 = end.y;
bool steep = false;
if (std::abs(x1 - x0) < std::abs(y1 - y0)) {
steep = true;
std::swap(x0, y0);
std::swap(x1, y1);
}
if (x1 < x0) {
std::swap(x0, x1);
std::swap(y0, y1);
}
for (int x = x0; x <= x1; ++x) {
float t = (x - x0) / (float)(x1 - x0);
int y = y0 * (1. - t) + y1 * t; // what is wrong here and how it works?
// int y = y0 + t * (y1 - y0); // this works fine
if (steep) {
this->point(Point(y, x));
} else {
this->point(Point(x, y));
}
}
}
calling:
// just create tgaimage instance like: this->image = new TGAImage(width, height, TGAImage::RGB);
Canvas* canvas = new Canvas(50, 50);
// store the drawing context
CanvasContext* _2dContext = canvas->createContext();
_2dContext->setColor(Canvas::COLOR_WHITE);
// call the method just given
_2dContext->line({5, 5}, {5, 20});
In fact, in the expression y0*(1.-t) + y1*t there are two casts from floating point to int, the addition is integer. Therefore, there are more rounding errors than in the first one y0 + (y1-y0)*t
There is a pedagogical interest though to write y0*(1.-t) + y1*t because 1-t and t are barycentric coordinates of the current point w.r.t the segment (x0,y0) - (x1,y1), and this prepares ground for the barycentric coordinates in a triangle
Thank you, great repository!