From a263b71828192c9bb4fa5cf3e3fdbfc14f341dcb Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Wed, 26 Jan 2011 20:40:56 +0000 Subject: [PATCH] Implements circular arcs in fpvectorial git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1463 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../fpvectorialsrc/dxfvectorialreader.pas | 9 +- .../fpvviewer/fpvectorialsrc/fpvectorial.pas | 3 +- .../fpvviewer/fpvectorialsrc/fpvtocanvas.pas | 83 ++++++++++++++----- applications/fpvviewer/fpvviewer.lpi | 1 - 4 files changed, 70 insertions(+), 26 deletions(-) diff --git a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas index b9897dd5b..4ce52c87b 100644 --- a/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas +++ b/applications/fpvviewer/fpvectorialsrc/dxfvectorialreader.pas @@ -314,7 +314,8 @@ begin for i := 0 to ATokens.Count - 1 do begin CurToken := TDXFToken(ATokens.Items[i]); - if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData) + if CurToken.StrValue = 'ARC' then ReadENTITIES_ARC(CurToken.Childs, AData) + else if CurToken.StrValue = 'CIRCLE' then ReadENTITIES_CIRCLE(CurToken.Childs, AData) else if CurToken.StrValue = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData) else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData) else if CurToken.StrValue = 'TEXT' then @@ -377,8 +378,8 @@ end; 20, 30 DXF: Y and Z values of center point (in OCS) 40 Radius 100 Subclass marker (AcDbArc) -50 Start angle -51 End angle +50 Start angle (degrees) +51 End angle (degrees) 210 Extrusion direction. (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector 220, 230 DXF: Y and Z values of extrusion direction (optional) } @@ -412,6 +413,8 @@ begin 20: CenterY := CurToken.FloatValue; 30: CenterZ := CurToken.FloatValue; 40: Radius := CurToken.FloatValue; + 50: StartAngle := CurToken.FloatValue; + 51: EndAngle := CurToken.FloatValue; end; end; diff --git a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas index 6c5119184..af0feaa86 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvectorial.pas @@ -139,6 +139,7 @@ type TvCircularArc = class(TvEntity) public CenterX, CenterY, CenterZ, Radius: Double; + {@@ The Angle is measured in degrees in relation to the positive X axis } StartAngle, EndAngle: Double; end; @@ -151,7 +152,7 @@ type public // Mandatory fields CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis: Double; - {@@ The Angle is measured in radians in relation to the positive X axis } + {@@ The Angle is measured in degrees in relation to the positive X axis } Angle: Double; // Calculated fields BoundingRect: TRect; diff --git a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas index f80ab900e..8900db1b6 100644 --- a/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas +++ b/applications/fpvviewer/fpvectorialsrc/fpvtocanvas.pas @@ -4,17 +4,28 @@ unit fpvtocanvas; interface +{$define USE_LCL_CANVAS} + uses - Classes, SysUtils, + Classes, SysUtils, Math, + {$ifdef USE_LCL_CANVAS} + Graphics, LCLIntf, + {$else} fpcanvas, + {$endif} fpvectorial; -procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas; +procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; + {$ifdef USE_LCL_CANVAS} + ADest: TCanvas; + {$else} + ADest: TFPCustomCanvas; + {$endif} ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); implementation -{function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint; +function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint; var sinus, cosinus : Extended; begin @@ -23,31 +34,46 @@ begin P.y := P.y - Fix.y; result.x := Round(p.x*cosinus + p.y*sinus) + fix.x ; result.y := Round(-p.x*sinus + p.y*cosinus) + Fix.y; -end;} +end; -procedure DrawRotatedEllipse(ADest: TFPCustomCanvas; CurEllipse: TvEllipse); -{var +procedure DrawRotatedEllipse( + {$ifdef USE_LCL_CANVAS} + ADest: TCanvas; + {$else} + ADest: TFPCustomCanvas; + {$endif} + CurEllipse: TvEllipse; + ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); +var PointList: array[0..6] of TPoint; f: TPoint; - dk: Integer;} + dk, x1, x2, y1, y2: Integer; begin -{ dk := Round(0.654 * Abs(y2-y1)); - f.x := CurEllipse.CenterX; - f.y := CurEllipse.CenterY - 1; - PointList[0] := Rotate2DPoint(Point(x1, f.y), f, Alpha) ; // Startpoint - PointList[1] := Rotate2DPoint(Point(x1, f.y - dk), f, Alpha); + {$ifdef USE_LCL_CANVAS} + CurEllipse.CalculateBoundingRectangle(); + x1 := CurEllipse.BoundingRect.Left; + x2 := CurEllipse.BoundingRect.Right; + y1 := CurEllipse.BoundingRect.Top; + y2 := CurEllipse.BoundingRect.Bottom; + + dk := Round(0.654 * Abs(y2-y1)); + f.x := Round(CurEllipse.CenterX); + f.y := Round(CurEllipse.CenterY - 1); + PointList[0] := Rotate2DPoint(Point(x1, f.y), f, CurEllipse.Angle) ; // Startpoint + PointList[1] := Rotate2DPoint(Point(x1, f.y - dk), f, CurEllipse.Angle); //Controlpoint of Startpoint first part - PointList[2] := Rotate2DPoint(Point(x2- 1, f.y - dk), f, Alpha); + PointList[2] := Rotate2DPoint(Point(x2- 1, f.y - dk), f, CurEllipse.Angle); //Controlpoint of secondpoint first part - PointList[3] := Rotate2DPoint(Point(x2 -1 , f.y), f, Alpha); + PointList[3] := Rotate2DPoint(Point(x2 -1 , f.y), f, CurEllipse.Angle); // Firstpoint of secondpart - PointList[4] := Rotate2DPoint(Point(x2-1 , f.y + dk), f, Alpha); + PointList[4] := Rotate2DPoint(Point(x2-1 , f.y + dk), f, CurEllipse.Angle); // Controllpoint of secondpart firstpoint - PointList[5] := Rotate2DPoint(Point(x1, f.y + dk), f, Alpha); + PointList[5] := Rotate2DPoint(Point(x1, f.y + dk), f, CurEllipse.Angle); // Conrollpoint of secondpart endpoint PointList[6] := PointList[0]; // Endpoint of // Back to the startpoint - PolyBezier(canvas.handle, Pointlist[0], 7);} + ADest.PolyBezier(Pointlist[0]); + {$endif} end; {@@ @@ -64,7 +90,12 @@ end; DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0); } -procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; ADest: TFPCustomCanvas; +procedure DrawFPVectorialToCanvas(ASource: TvVectorialDocument; + {$ifdef USE_LCL_CANVAS} + ADest: TCanvas; + {$else} + ADest: TFPCustomCanvas; + {$endif} ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0); var i, j, k: Integer; @@ -80,7 +111,7 @@ var CurEntity: TvEntity; CurCircle: TvCircle; CurEllipse: TvEllipse; - CurCircularArc: TvCircularArc; + CurArc: TvCircularArc; begin {$ifdef FPVECTORIALDEBUG} WriteLn(':>DrawFPVectorialToCanvas'); @@ -161,8 +192,18 @@ begin end else if CurEntity is TvCircularArc then begin - CurCircularArc := CurEntity as TvCircularArc; -// ADest.Arc(ADest, CurEllipse); + CurArc := CurEntity as TvCircularArc; + {$ifdef USE_LCL_CANVAS} + // Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer); + ADest.Arc( + Round(ADestX + AmulX * (CurArc.CenterX - CurArc.Radius)), + Round(ADestY + AmulY * (CurArc.CenterY - CurArc.Radius)), + Round(ADestX + AmulX * (CurArc.CenterX + CurArc.Radius)), + Round(ADestY + AmulY * (CurArc.CenterY + CurArc.Radius)), + Round(16*CurArc.StartAngle), + Round(16*CurArc.EndAngle - CurArc.StartAngle) + ); + {$endif} end; end; diff --git a/applications/fpvviewer/fpvviewer.lpi b/applications/fpvviewer/fpvviewer.lpi index 75c729b67..bebd54f6d 100644 --- a/applications/fpvviewer/fpvviewer.lpi +++ b/applications/fpvviewer/fpvviewer.lpi @@ -7,7 +7,6 @@ -