Hi, Try this: procedure DrawCurve; var p1, p2, p3 : TPoint; mp1, mp2 : TPoint; // chord midpoints c : TPoint; // centre of circle rad : double; // radius of circle r1, r2 : TPoint; // bounding rectangle (square) m1, m2 : double; // slope of 2 chords x : double; // temp angrot, angp1p2, angp2p3 : double; begin SetPenAndBrush; DrawingCanvas.Pen.Style := psDash; // only works if pen width = 1 p1 := MakePoint(Data.tbEntity.FieldByName('Pt1x').AsFloat*Option.Factor, Data.tbEntity.FieldByName('Pt1y').AsFloat*Option.Factor); p2 := MakePoint(Data.tbEntity.FieldByName('Pt2x').AsFloat*Option.Factor, Data.tbEntity.FieldByName('Pt2y').AsFloat*Option.Factor); p3 := MakePoint(Data.tbEntity.FieldByName('Pt3x').AsFloat*Option.Factor, Data.tbEntity.FieldByName('Pt3y').AsFloat*Option.Factor); if ((p1.x = 0) and (p1.y = 0)) and ((p2.x = 0) and (p2.y = 0)) and ((p3.x = 0) and (p3.y = 0)) then begin exit; end; // sanity check - 3 different points if ((p1.x = p2.x) and (p1.y = p2.y)) or ((p1.x = p3.x) and (p1.y = p3.y)) or ((p3.x = p2.x) and (p3.y = p2.y)) then begin ErrorMsg('All 3 points on a curve must be different.'); Data.tbEntity.delete; exit; end; // determine direction of curve rotation try angp1p2 := math.arctan2((p2.y-p1.y), (p2.X-p1.X)); angp2p3 := math.arctan2((p3.y-p2.y), (p3.X-p2.X)); angrot := angp2p3 - angp1p2; except angrot := 0; // straight line end; // normalise the angle to between -pi..pi if angrot > pi then angrot := angrot - 2*pi else if angrot < (-pi) then angrot := angrot + 2*pi; if abs(angrot) < 0.05 then begin // Cannot draw a curve through points in a straight line. // draw a straight line instead DrawingCanvas.MoveTo(p1.x, p1.y); DrawingCanvas.LineTo(p3.x, p3.y); exit; end; if angrot > 0 then begin // clockwise, so reverse start and end points mp1.x := p1.x; mp1.y := p1.y; p1.x := p3.x; p1.y := p3.y; p3.x := mp1.x; p3.y := mp1.y; end; // chord midpoint between p1 and p2 mp1.X := (p1.X + p2.X) div 2; mp1.Y := (p1.Y + p2.Y) div 2; // chord midpoint between p2 and p3 mp2.X := (p3.X + p2.X) div 2; mp2.Y := (p3.Y + p2.Y) div 2; // slope of lines 1 and 2 try m1 := 1.0*(p2.y-p1.y)/(p2.x-p1.x); except m1 := maxint; // for now (vertical line) end; try m2 := 1.0*(p3.y-p2.y)/(p3.x-p2.x); except m2 := maxint; // for now (vertical line) end; // don't let these slopes quite get to zero if (m1 < 0.01) and (m1 > 0) then m1 := 0.01; if (m1 > -0.01) and (m1 < 0) then m1 := -0.01; if (m2 < 0.01) and (m2 > 0) then m2 := 0.01; if (m2 > -0.01) and (m2 < 0) then m2 := -0.01; // slopes of perpendicular lines, pointing to centre of circle try m1 := -1/m1; except m1 := maxint*iif(p3.Y<p2.Y,-1,1); end; try m2 := -1/m2; except m2 := maxint*iif(p1.Y<p2.Y,-1,1); end; // x of circle centre try x := (mp2.y-mp1.y-(m2*mp2.x)+(m1*mp1.x))/(m1-m2); except // divide by zero, lines are parallel, should never happen but just in case: // draw a straight line instead DrawingCanvas.MoveTo(p1.x, p1.y); DrawingCanvas.LineTo(p3.x, p3.y); exit; end; // y of circle centre c.y := round(mp1.y+m1*(x-mp1.x)); c.X := round(x); // radius rad := sqrt(sqr(p2.X-c.x)+sqr(p2.Y-c.Y)); // bounding square and circle r1.x := c.X - round(rad); r2.x := c.X + round(rad); r1.y := c.y - round(rad); r2.y := c.y + round(rad); DrawingCanvas.Arc(r1.X, r1.y, r2.x, r2.y, p1.x,p1.y,p3.x,p3.y); end;
HTH, Steve _____ From: Marshland Engineering [mailto:marshl...@marshland.co.nz] Sent: Tuesday, 18 January 2011 9:03 p.m. To: delphi@delphi.org.nz Subject: [DUG] Arc's Is there an easy way of drawing an arc ? I have center, start and end co-ordinates as XY. >From what I can see, I need to look at least 16 combinations to work out the perimeter size depending in which quadrant the start and ends are in. procedure Arc(X1, Y1, X2, Y2, X3, Y3, X4, Y4: Integer); Use Arc to draw an elliptically curved line with the current Pen. The arc traverses the perimeter of an ellipse that is bounded by the points (X1,Y1) and (X2,Y2). The arc is drawn following the perimeter of the ellipse, counterclockwise, from the starting point to the ending point. The starting point is defined by the intersection of the ellipse and a line defined by the center of the ellipse and (X3,Y3). The ending point is defined by the intersection of the ellipse and a line defined by the center of the ellipse and (X4, Y4).
_______________________________________________ NZ Borland Developers Group - Delphi mailing list Post: delphi@delphi.org.nz Admin: http://delphi.org.nz/mailman/listinfo/delphi Unsubscribe: send an email to delphi-requ...@delphi.org.nz with Subject: unsubscribe