/* * 15 14 13 * 0 o o o o o 12 * * 1 o o 11 * * 2 o o 10 * * 3 o o 9 * * 4 o o o o o 8 * 5 6 7 */ void enumerateLEDImagePoints(std::vector<calib::LEDCalibContainer> &LEDContainers) { int nContainers = LEDContainers.size(); for(int cContainer = 0; cContainer < nContainers; ++cContainer) { calib::LEDCalibContainer &curContainer = LEDContainers[cContainer]; std::vector<calib::LEDCalibSample> &samples = curContainer.getSamples(); int nSamples = samples.size(); for(int cSample = 0; cSample < nSamples; ++cSample) { std::vector<cv::Point2f> &imagePoints = samples[cSample].image_points; swapPoints(imagePoints[0], imagePoints[12]); // swap 0 and 12 swapPoints(imagePoints[1], imagePoints[11]); // swap 1 and 11 swapPoints(imagePoints[2], imagePoints[10]); // swap 2 and 10 swapPoints(imagePoints[3], imagePoints[9]); // swap 3 and 9 swapPoints(imagePoints[4], imagePoints[8]); // swap 4 and 8 swapPoints(imagePoints[13], imagePoints[15]); // swap 13 and 15 swapPoints(imagePoints[5], imagePoints[7]); // swap 5 and 7 } } }
void LDLQuadLine::swapPointsIfNeeded(void) { if (swapNeeded(0, 1, 2, 3)) { // The original order is wrong; we'll try to fix it to produce a // standard convex quad. if (!swapNeeded(0, 1, 3, 2)) { reportBadVertexOrder(0, 1, 3, 2); swapPoints(2, 3); } else if (!swapNeeded(0, 2, 1, 3)) { reportBadVertexOrder(0, 2, 1, 3); swapPoints(1, 2); } else if (!swapNeeded(0, 2, 3, 1)) { reportBadVertexOrder(0, 2, 3, 1); rotPoints(1, 2, 3); } else if (!swapNeeded(0, 3, 1, 2)) { reportBadVertexOrder(0, 3, 1, 2); rotPoints(1, 3, 2); } else if (!swapNeeded(0, 3, 2, 1)) { reportBadVertexOrder(0, 3, 2, 1); swapPoints(1, 3); } else { // None of the possible point orders resulted in an acceptable quad, // so this quad must be concave or non-planar. m_valid = false; } m_actionFlags.bfcClip = false; } }
void SoftwareRendererImp::rasterize_triangle( float x0, float y0, float x1, float y1, float x2, float y2, Color color ) { //modify task 2: scale up the point location: /* x0 = 100.0 + 000.0; y0 = 000.0; x1 = 100.0 + 000.0; y1 = 100.0; x2 = 100.0 + 100.0; y2 = 100.0; */ //printf("Color: (%f, %f, %f, %f)\n", color.r, color.g, color.b, color.a); scale_point(x0, y0, sample_rate); scale_point(x1, y1, sample_rate); scale_point(x2, y2, sample_rate); // Task 2: // Implement triangle rasterization // Method 1: use bounding box, does not consider "edge rule" if (!cclock(x0, y0, x1, y1, x2, y2)) { //printf("before swap: (%f, %f, %f, %f)", x0, y0, x1, y1); swapPoints(x1, y1, x2, y2); //printf("after swap: (%f, %f, %f, %f)", x0, y0, x1, y1); } float lowX, highX, lowY, highY; lowX = (floor(min(min(x0, x1), x2))) + 0.5; lowY = (floor(min(min(y0, y1), y2))) + 0.5; highX = (ceil(max(max(x0, x1), x2))) - 0.5; highY = (ceil(max(max(y0, y1), y2))) - 0.5; for ( float x = lowX; x <= highX; x += 1 ) { for (float y = lowY; y <= highY; y += 1 ) { if (lineSide(x, y, x0, y0, x1, y1) && lineSide(x, y, x1, y1, x2, y2) && lineSide(x, y, x2, y2, x0, y0)) { rasterize_point(x, y, color); } } } }
void Line::Draw(Frame* target) { if (p2.X < p1.X) swapPoints(); Point start = p1; Point end = p2; bool flipHoriz = false; if (end.Y < start.Y) { start.Y *= -1; end.Y *= -1; flipHoriz = true; } bool flipBisec = false; if ((end.X - start.X) < (end.Y - start.Y)) { int tmp = start.X; start.X = start.Y; start.Y = tmp; tmp = end.X; end.X = end.Y; end.Y = tmp; flipBisec = true; } target->SetPoint(start); while (start.X < end.X) { start.X++; if ((end.Y - start.Y) * 2 > end.X - start.X) start.Y++; target->SetPoint(start); } }
// This is a Bresenham-based linescan function using mega pixels // All cases use similar structure to the standard case, just with different values for dFa, dFb, and p void loeschLineScanMega(My2DPoint p1, My2DPoint p2) { if (p1.x > p2.x) // if the points are in the wrong order, swap them first swapPoints(p1, p2); // declare and initialize values int dY = p2.y - p1.y; int dX = p2.x - p1.x; float m = (float)dY / (float)dX; // calculate and store slope int dFa; int dFb; int p; int currX = 0; int currY = 0; if (dX == 0) { // vertical line if (p1.y < p2.y) { // if p1 is lower, draw starting from p1 for (int i = 0; i < dY - (dY % 5); i += 5) drawMegaPixel(p1.x, p1.y + i); } else // otherwise draw starting from p2 { for (int i = 0; i < dY - (dY % 5); i += 5) drawMegaPixel(p2.x, p2.y + i); } } else if (m >= 0.0 && m <= 1.0) { // standard case ( 0 <= m <= 1 ) // calculate dFa and dFb, as well as the initial value for p dFa = 10 * dY - 10 * dX; dFb = 10 * dY; p = 10 * dY - 5 * dX; // draw the initial point drawMegaPixel(p1.x, p1.y); for (int k = 5; k <= dX - (dX % 5); k += 5) { // k is the current x value if (p < 0) // if p is below the midpoint, use dFb p += dFb; else { // otherwise p is above midpoint, use dFa currY += 5; p += dFa; } drawMegaPixel(p1.x + k, p1.y + currY); // draw a pixel at the current x and y } } else if (m > 1.0) { // slope greater than 1 ( m < 1 ) dFa = 10 * (dX - dY); dFb = 10 * dX; p = 10 * dX - 5 * dY; drawMegaPixel(p1.x, p1.y); for (int k = 5; k <= dY - (dY % 5); k += 5) { // k is the current y value if (p < 0) p += dFb; else { currX += 5; p += dFa; } drawMegaPixel(p1.x + currX, p1.y + k); } } else if (m < 0.0 && m >= -1.0) { // negative slope ( 0 < m <= -1 ) dFa = 10 * (dY + dX); dFb = 10 * dY; p = 10 * dY + 5 * dX; drawMegaPixel(p1.x, p1.y); for (int k = 5; k <= dX - (dX % 5); k += 5) { // k is the current x value if (p > 0) p += dFb; else { currY += 5; p += dFa; } drawMegaPixel(p1.x + k, p1.y - currY); } } else { // slope must be negative and less than -1 ( m < -1 ) dY *= -1; // make dY positive (in order to emulate the case m < 1) dFa = 10 * (dX - dY); dFb = 10 * dX; p = 10 * dX - 5 * dY; drawMegaPixel(p1.x, p1.y); for (int k = 5; k <= dY - (dY % 5); k += 5) { // k is the current y value if (p < 0) p += dFb; else { currX += 5; p += dFa; } drawMegaPixel(p1.x + currX, p1.y - k); } } }
// [UNUSED] This is a Bresenham-based linescan function (DOES NOT use mega pixels) void loeschLineScan(My2DPoint p1, My2DPoint p2) { if (p1.x > p2.x) // if the points are in the wrong order, swap them first swapPoints(p1, p2); int dY = p2.y - p1.y; int dX = p2.x - p1.x; float m = (float)dY / (float)dX; // slope int dFa; int dFb; int p; int currX = 0; int currY = 0; if (dX == 0) { // vertical line if (p1.y < p2.y) { glBegin(GL_POINTS); for (int i = 0; i < dY; i++) glVertex2i(p1.x, p1.y + i); glEnd(); } else { glBegin(GL_POINTS); for (int i = 0; i < dY; i++) glVertex2i(p2.x, p2.y + i); glEnd(); } } else if(m >= 0.0 && m <= 1.0) { // standard case dFa = 2 * (dY - dX); dFb = 2 * dY; p = 2 * dY - dX; glBegin(GL_POINTS); glVertex2i(p1.x, p1.y); for (int k = 1; k <= dX; k++) { if (p < 0) p += dFb; else { currY++; p += dFa; } glVertex2i(p1.x + k, p1.y + currY); } glEnd(); } else if (m > 1.0) { // slope greater than 1 dFa = 2 * (dX - dY); dFb = 2 * dX; p = 2 * dX - dY; glBegin(GL_POINTS); glVertex2i(p1.x, p1.y); for (int k = 1; k <= dY; k++) { if (p < 0) p += dFb; else { currX++; p += dFa; } glVertex2i(p1.x + currX, p1.y + k); } glEnd(); } else if (m < 0.0 && m >= -1.0) { // negative slope dFa = 2 * (dY + dX); dFb = 2 * dY; p = 2 * dY + dX; glBegin(GL_POINTS); glVertex2i(p1.x, p1.y); for (int k = 1; k <= dX; k++) { if (p > 0) p += dFb; else { currY++; p += dFa; } glVertex2i(p1.x + k, p1.y - currY); } glEnd(); } else { // slope must be negative and less than -1 dY *= -1; dFa = 2 * (dX - dY); dFb = 2 * dX; p = dX * 2 - dY; glBegin(GL_POINTS); glVertex2i(p1.x, p1.y); for (int k = 1; k <= dY; k++) { if (p < 0) p += dFb; else { currX++; p += dFa; } glVertex2i(p1.x + currX, p1.y - k); } glEnd(); } }
void SoftwareRendererImp::rasterize_line( float x0, float y0, float x1, float y1, Color color) { // Task 1: // Implement line rasterization scale_point(x0, y0, sample_rate); scale_point(x1, y1, sample_rate); if (x0 > x1) { swapPoints(x0, y0, x1, y1); } int sx0 = (int) floor(x0); int sy0 = (int) floor(y0); int sx1 = (int) floor(x1); int sy1 = (int) floor(y1); float k; if (sx1 == sx0) { int low = min(sy0, sy1); int high = max(sy0, sy1); for ( int y = low; y <= high; y++ ) { SoftwareRendererImp::rasterize_point((float) x0, (float) y, color); } } else { k = (y1 - y0)/(x1 - x0); //fitst positive oct if (0.0 <= k && k <= 1.0) { int dx = sx1 - sx0, dy = sy1 - sy0, y = sy0, eps = 0; for ( int x = sx0; x <= sx1; x++ ) { SoftwareRendererImp::rasterize_point((float) x, (float) y, color); eps += dy; if ( (eps << 1) >= dx ) { y++; eps -= dx; } } } //second positive oct if (k > 1.0 && sx1 != sx0) { int dx = sx1 - sx0, dy = sy1 - sy0, x = sx0, eps = 0; for ( int y = sy0; y <= sy1; y++ ) { SoftwareRendererImp::rasterize_point((float) x, (float) y, color); eps += dx; if ( (eps << 1) >= dy ) { x++; eps -= dy; } } } if (k <= -1.0) { int dx = sx1 - sx0, dy = sy1 - sy0, x = sx0, eps = 0; for ( int y = sy0; y >= sy1; y-- ) { SoftwareRendererImp::rasterize_point((float) x, (float) y, color); eps -= dx; if ( (eps << 1) <= dy ) { x++; eps -= dy; } } } if (-1.0 <= k && k <= 0.0) { int dx = sx1 - sx0, dy = sy1 - sy0, y = sy0, eps = 0; for ( int x = sx0; x <= sx1; x++ ) { SoftwareRendererImp::rasterize_point((float) x, (float) y, color); eps += dy; if ( (eps << 1) <= -dx ) { y--; eps += dx; } } } } }