Application of DDA algorithm and Bresenham algorithm in game

Source: Internet
Author: User

In a role-playing or instant strategy game, the character is often the best way to go to a designated place. The ground situation of the game scene is complex, and the scene is big, if blindly search, for example, the blind and poor lifting method, then almost to traverse the whole scene, the efficiency is very low, causing the role response speed is too slow, practice proved to be not suitable for the network game Pathfinding method. The heuristic search algorithm also appears inefficient in the case of fewer obstacles.

DDA algorithm and Bresenham algorithm are two common algorithms for drawing straight lines in game pathfinding.

Before enumerating the two algorithms, I first define the structure code of the coordinates:

struct pixelnode{uint16_t x;uint16_t y;};

The numerical differential line algorithm (DDA) method is the simplest one in the linear generation algorithm, which is a single-step straight line generation algorithm. Its algorithm is this: first, according to the slope of the line to determine whether to step in the x direction or in the Y direction, and then step in the direction of each step into a point (pixel), along the other coordinate variable k,k is the slope of the line, because it is output to the lattice device, so it is necessary to each computed a pair of coordinates to round

The implementation of the specific algorithm, in addition to the judgment is in accordance with the X direction or in accordance with the Y direction of stepping, but also to consider the direction of the line, that is, the relationship between the start and end.

Description and principle of the DDA algorithm:

Set (X1,y1) and (X2,y2) are the starting and ending coordinates of the desired line, respectively, by the differential equation of the line

You can generate a line by calculating the change in Y caused by the increment x in the x direction:

You can also generate a line by calculating the x change caused by the Y-direction increment y:


The larger of the selected x2-x1 and y2-y1 as the step direction (assuming the x2-x1 is larger), the increment in that direction is one pixel unit (x=1).

The formula (2-1) is then used to calculate the increment of the other direction (y= x m=m). by recursion formula (2-2) to (2-5), each calculated (xi+1,yi+1)

After rounding to the display output, the scanned converted line is obtained. The reason for taking the larger of x2-x1 and y2-y1 as the step direction is to consider along

The pixels of the line distribution should be uniform, as can be seen in the.
In addition, the algorithm should also pay attention to the direction of the line generation, in order to determine whether Δx and Δy are positive or negative.

So his implementation steps are described in this way:

1. The coordinates of the two ends of the known line: (X1,y1), (X2,y2)

2. Color of the known draw line: color
3. Calculate the amount of change in two directions: dx=x2-x1 dy=y2-y1

4. Find out the absolute value of the maximum variation in two directions:
Steps=max (|dx|,|dy|)

5, calculate the increment of two direction (consider the generation direction): Xin=dx/steps yin=dy/steps

6. Set the initial pixel coordinates: X=X1,Y=Y1

7, using the loop to achieve a straight line drawing:

for (i=1;i<=steps;i++)  {     putpixel (x,y,color);/* at (x, y), Draw dots in color color */     x=x+xin;       Y=y+yin;     }

Here's a code to illustrate the algorithm:

BOOL Dda::calclinenodes (int x1, int y1, int x2, int y2,vector<pixelnode>& pointlist) {float increx,increy,x,y;i NT Steps,i;  if (x1 = = x2 && y1 = = y2) {return false;} Pointlist.clear (); if (ABS (X2-X1) > abs (y2-y1)) {  steps= abs (X2-X1);  } else {steps = ABS (Y2-Y1);} Increx = (float) (x2-x1)/steps;  Increy = (float) (y2-y1)/steps; x = x1;  y = y1;  for (i = 1;i <= steps;i + +)  {//putpixel (x, y, color);//at ((x, y), point   Pixelnode p (x, y) in color color;p ointlist.push_ Back (p); x+=increx;y+=increy;     }    return true;}

But in fact, the numerical differential method (DDA method) produces a straight line more accurate, and logic is simple, easy to implement with hardware, but the steps of X, Y and K must be represented by a floating-point number, each step to the X or Y rounded after rounding, not conducive to rasterization or lattice output. A line is generated for a longer time.

Features and principles of the Bresenham algorithm:

determined by the slope of the line selected in the x direction or y increment (minus) each time in the direction 1 unit, the increment (minus) of the other variable is 0 or 1 , depending on the distance between the actual line and the nearest raster grid point, the maximum error for this distance is 0.5 .

assumed line slope k 0~1 x direction each increment 1 units, decision y 0 or 1

Set the current point of the line is (xi,y)

Line current Raster point is (xi,yi)

< /span> The point of the next line should be (XI+1,Y+K)    < Span style= "White-space:pre" > The raster point of the next line is the right raster point (xi+1,yi) ( y direction increment 0) or for right glazing dot (xi+1,yi+1) ( y direction increment 1 )

The error of the lower grating point where the line and its vertical direction is D , there are: d= (y+k) –yi , and

     0≤d≤1   &NBSP;&NBSP, when d<0.5 Span style= "font-family: The song Body" >: The next pixel should take the right raster point (xi+1,yi) &NBSP;&NBSP;&NBSP; when d≥0.5 : Next pixel should be taken right glazing dot (xi+1,yi+1)

Here I give a partial implementation of the Code:

The return list contains the starting point, which does not contain the target point bool Bresenham::calclinenodes (uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, std::vector< pixelnode>& Rnodesvec) {if (x1 = = x2 && y1 = = y2) {return false;}    Rnodesvec.clear (); int dx = ABS (X2-X1);//x int dy = ABS (y2-y1);//y int p = (2 * dy)-DX; P = 2 y-x int pointx = x1;//start coordinate x int pointy = y1;//start coordinate y int stepx = 0;int stepy = 0;if (Y1 < y2) {Stepy  = 1;//y Increment}else//y1 > y2{stepy = -1;//y decrement}if (X1 < x2) {stepx = 1;//x increment}else{stepx = -1;//x decrement}//Reach first starting point Pixelnode    pt0;pt0.x = Pointx;pt0.y = Pointy;rnodesvec.push_back (PT0); if (dx > Dy)//cross-span large, x for step {int twody = 2 * DY;//2 Yint TWODYDX = 2 * (DY-DX);//2 (Y-X) while (pointx! = x2) {P Ointx + = stepx;if (P < 0) {p + = Twody;} Else{pointy + = stepy;p + = TWODYDX;} Pixelnode pt;pt.x = Pointx;pt.y = Pointy;rnodesvec.push_back (PT);}} else//longitudinal span large, with y as step {int TWODX = 2 * DX;//2 Xint Twodxdy = 2 * (dx-dy);//2 (x-y) while (pointy! = y2) {pointy + = St Epy; if (P < 0) {p + = Twodx;} Else{pointx + = stepx;p + = Twodxdy;} Pixelnode pt;pt.x = Pointx;pt.y = Pointy;rnodesvec.push_back (PT);}} return true;}

Application of DDA algorithm and Bresenham algorithm in game

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.