Implementing the 3D image engine from scratch: (2) it is not easy to draw 2D straight lines.

Source: Internet
Author: User

1. Mathematical Analysis

1) draw a straight line

I thought it would be easy to draw a straight line. Just take a straight line formula and traverse X to find Y. Isn't that true. Take the 2D line as an example, because the 3D line only introduces a zcoordinate. Key problem: the straight lines we have learned in mathematics are based on the real number field. On the computer screen, the straight lines drawn are based on the positive integer domain. You can imagine this situation, how do I draw a line at a certain point of x = 1, y = 0.01 on the screen? Compare the line in the real number field with the line based on the positive integer field:

Why is a straight line discontinuous in a positive integer? Do you still remember the slope definition: slope M = Dy/dx = (Y1-y0)/(x1-X0)

This means that when the X coordinate increases by 1, the Y coordinate increases by M. This is the root cause of the above situation.

 

2) bresenham Algorithm

This algorithm was invented by bresenham in 1965. What did it do? In fact, the idea is very simple, that is, moving a pixel per x, consider how y should move. Why do we need to pay attention to the bresenham algorithm? We found that this algorithm only performs addition and subtraction, which is very suitable for computer operations. This algorithm is very fast.

This algorithm divides a line into two types: one is the line with the slope <1, that is, the line near the X axis. The other is the line with a slope greater than 1, that is, the line near the Y axis.

Take a line near the X axis as an example,

The core of the bresenham algorithm is how to determine the movement of Y after X plus 1. Obviously, Dy <dx is near the X axis. Therefore, an intuitive idea is to save an error accumulative variable. Every time X is added with 1, the error variable accumulates a dy. If the cumulative error is less than or equal to DX, y does not move. If the cumulative error is greater than dx, Y increases by 1 and the cumulative error is reduced by dx. In this way, the algorithm will keep minimizing the error between the grating line and the actual line.

 

2. function implementation

An example is provided here to implement the above algorithm, but only the near-x-axis is allowed and the implementation logic is clearly displayed from the top left to the bottom right. The general draw line has been implemented in the source code and can be downloaded and obtained.

Int dx = x1-x0; <br/> int DY = Y1-y0; <br/> int error = 0; <br/> If (dx> Dy) // near X axis <br/>{< br/> for (INT x = x0, y = y0; x <= x1; ++ X) <br/>{< br/> drawpixel (X, Y, color); <br/> error + = Dy; // accumulative error </P> <p> If (error> dx) <br/>{< br/> error-= DX; <br/> ++ y; <br/>}< br/>}

 

The complete code for all cases is as follows, with some optimizations in the calculation of errors. The starting value is more centered, rather than zero.

Int _ cppyin_3dlib: drawline (INT x0, int y0, int X1, int Y1, DWORD color) <br/>{< br/> int X, Y, dx, Dy, dx2, dy2, xstep, ystep, error, index; <br/> X = x0; <br/> Y = y0; <br/> dx = x1-x0; <br/> DY = Y1-y0; </P> <p> If (dx> = 0) // draw from left to right <br/>{< br/> xstep = 1; // X step forward 1 <br/>}< br/> else // draw from right to left <br/>{< br/> xstep =-1; // X step negative 1 <br/> dx =-DX; // obtain the absolute value <br/>}</P> <p> If (dy> = 0) // draw from top down <br/>{< br/> ystep = 1; // y step forward 1 <br/>}< br/> else // draw from bottom up <br/>{< br/> ystep =-1; // step Y minus 1 <br/> DY =-dy; // obtain the absolute value <br/>}</P> <p> dx2 = DX <1; // 2 * DX <br/> dy2 = Dy <1; // 2 * dy </P> <p> If (dx> Dy) // a straight line near the X axis <br/>{< br/> error = dy2-DX; <br/> for (Index = 0; index <= DX; ++ index) <br/>{< br/> drawpixel (X, Y, color); <br/> If (error> = 0) <br/>{< br/> error-= dx2; <br/> Y + = ystep; <br/>}< br/> error + = dy2; <br/> X + = xstep; <br/>}< br/> else // a line near the Y axis <br/>{< br/> error = dx2-dy; <br/> for (Index = 0; index <= Dy; ++ index) <br/>{< br/> drawpixel (X, Y, color ); <br/> If (error> = 0) <br/> {<br/> error-= dy2; <br/> X + = xstep; <br/>}< br/> error + = dx2; <br/> Y + = ystep; <br/>}</P> <p> return 1; <br/>}

 

3. Download source code

This function is used in this example to draw 500 lines of random colors in the window, as shown below:

 

Project source code download:> click to enter the download page <

 

4. Supplemental updates

There are also some algorithms to draw a straight line, and the speed is faster, such:

Run-Slicing

Symmetric double step

Quadruple step

If you have time, I will implement it one by one. If you have already implemented it, please share it with us. Thank you.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.