bresline.c |
| THIS CODE NOT MINE //============================================================================ // b r e s l i n e . c // // VERSION 4: draws from both ends and calculates single offset into FB. // (takes advantage of line symmetry). FIXES MIDPOINT PROBLEM // WHEN DRAWING FROM BOTH ENDS. ALSO MORE EFFICIENT! // Programmer: Kenny Hoff // Date: 11/08/95 // Purpose: To implement the Bresenham's line drawing algorithm for all // slopes and line directions (using minimal routines). //============================================================================ // EXTERNALLY DEFINED FRAMEBUFFER AND FRAMEBUFFER DIMENSIONS (WIDTH)) extern unsigned char far* FrameBuffer; extern int WIDTH; void BresLine(int Ax, int Ay, int Bx, int By, unsigned char Color) { int dX, dY, fbXincr, fbYincr, fbXYincr, dPr, dPru, P; //------------------------------------------------------------------------ // STORE THE FRAMEBUFFER ENDPOINT-ADDRESSES (A AND B) //------------------------------------------------------------------------ unsigned char far* AfbAddr = &FrameBuffer[Ay*WIDTH+Ax]; unsigned char far* BfbAddr = &FrameBuffer[By*WIDTH+Bx]; //------------------------------------------------------------------------ // DETERMINE AMOUNT TO INCREMENT FRAMEBUFFER TO GET TO SUBSEQUENT POINTS // (ALSO, STORE THE ABSOLUTE VALUE OF THE CHANGE IN X AND Y FOR THE LINE) //------------------------------------------------------------------------ fbXincr=1; if ( (dX=Bx-Ax) >= 0) goto AFTERNEGX; dX=-dX; fbXincr=-1; AFTERNEGX: fbYincr=WIDTH; if ( (dY=By-Ay) >= 0) goto AFTERNEGY; fbYincr=-WIDTH; dY=-dY; AFTERNEGY: fbXYincr = fbXincr+fbYincr; //------------------------------------------------------------------------ // DETERMINE INDEPENDENT VARIABLE (ONE THAT ALWAYS INCREMENTS BY 1 (OR -1) ) // AND INITIATE APPROPRIATE LINE DRAWING ROUTINE (BASED ON FIRST OCTANT // ALWAYS). THE X AND Y'S MAY BE FLIPPED IF Y IS THE INDEPENDENT VARIABLE. //------------------------------------------------------------------------ if (dY > dX) goto YisIndependent; // CHECK IF X OR Y IS INDEPENDENT VARIABLE // XisIndependent: dPr = dY+dY; // AMOUNT TO INCREMENT DECISION IF RIGHT IS CHOSEN (always) P = -dX; // DECISION VARIABLE START VALUE dPru = P+P; // AMOUNT TO INCREMENT DECISION IF UP IS CHOSEN dY = dX>>1; // COUNTER FOR HALF OF LINE (COMING FROM BOTH ENDS) XLOOP: // PROCESS EACH POINT IN THE LINE ONE AT A TIME (use dY as loop counter) *AfbAddr=Color; // PLOT THE PIXEL FROM END A *BfbAddr=Color; // PLOT THE PIXEL FROM END B if ((P+=dPr) > 0) goto RightAndUp; // INCREMENT DECISION, CHECK IF THE PIXEL IS GOING RIGHT AND UP // Up: AfbAddr+=fbXincr; // ADVANCE TO NEXT POINT FROM END A BfbAddr-=fbXincr; // ADVANCE TO NEXT POINT FROM END B if ((dY=dY-1) > 0) goto XLOOP; // DECREMENT LOOP VARIABLE AND LOOP *AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT LAST PT FROM END A if ((dX & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS) *BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS) return; RightAndUp: AfbAddr+=fbXYincr; // ADVANCE TO NEXT POINT FROM END A BfbAddr-=fbXYincr; // ADVANCE TO NEXT POINT FROM END B P+=dPru; // INCREMENT DECISION (for up) if ((dY=dY-1) > 0) goto XLOOP; // DECREMENT LOOP VARIABLE AND LOOP *AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT LAST PT FROM END A if ((dX & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS) *BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS) return; YisIndependent: dPr = dX+dX; // AMOUNT TO INCREMENT DECISION IF RIGHT IS CHOSEN (always) P = -dY; // DECISION VARIABLE START VALUE dPru = P+P; // AMOUNT TO INCREMENT DECISION IF UP IS CHOSEN dX = dY>>1; // COUNTER FOR HALF OF LINE (COMING FROM BOTH ENDS) YLOOP: // PROCESS EACH POINT IN THE LINE ONE AT A TIME (use dX as loop counter) *AfbAddr=Color; // PLOT THE PIXEL FROM END A *BfbAddr=Color; // PLOT THE PIXEL FROM END B if ((P+=dPr) > 0) goto RightAndUp2;// INCREMENT DECISION, CHECK IF THE PIXEL IS GOING RIGHT AND UP // Up: AfbAddr+=fbYincr; // ADVANCE TO NEXT POINT FROM END A BfbAddr-=fbYincr; // ADVANCE TO NEXT POINT FROM END B if ((dX=dX-1) > 0) goto YLOOP; // DECREMENT LOOP VARIABLE AND LOOP *AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT THE LAST POINT FROM END A if ((dY & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS) *BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS) return; RightAndUp2: AfbAddr+=fbXYincr; // ADVANCE TO NEXT POINT FROM END A BfbAddr-=fbXYincr; // ADVANCE TO NEXT POINT FROM END B P+=dPru; // INCREMENT DECISION (for up) if ((dX=dX-1) > 0) goto YLOOP; // DECREMENT LOOP VARIABLE AND LOOP *AfbAddr=Color; // (FIX MIDPOINT PROBLEM) PLOT THE LAST POINT FROM END A if ((dY & 1) == 0) return; // FINISHED IF INDEPENDENT IS EVEN (ODD # STEPS) *BfbAddr=Color; // PLOT LAST PT FROM END B IF INDEPENDENT IS ODD (EVEN # STEPS) return; } |
James Little |