Implements circular arcs in fpvectorial

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@1463 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat 2011-01-26 20:40:56 +00:00
parent c079c6138b
commit a263b71828
4 changed files with 70 additions and 26 deletions

View File

@ -314,7 +314,8 @@ begin
for i := 0 to ATokens.Count - 1 do for i := 0 to ATokens.Count - 1 do
begin begin
CurToken := TDXFToken(ATokens.Items[i]); 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 = 'ELLIPSE' then ReadENTITIES_ELLIPSE(CurToken.Childs, AData)
else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData) else if CurToken.StrValue = 'LINE' then ReadENTITIES_LINE(CurToken.Childs, AData)
else if CurToken.StrValue = 'TEXT' then else if CurToken.StrValue = 'TEXT' then
@ -377,8 +378,8 @@ end;
20, 30 DXF: Y and Z values of center point (in OCS) 20, 30 DXF: Y and Z values of center point (in OCS)
40 Radius 40 Radius
100 Subclass marker (AcDbArc) 100 Subclass marker (AcDbArc)
50 Start angle 50 Start angle (degrees)
51 End angle 51 End angle (degrees)
210 Extrusion direction. (optional; default = 0, 0, 1) DXF: X value; APP: 3D vector 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) 220, 230 DXF: Y and Z values of extrusion direction (optional)
} }
@ -412,6 +413,8 @@ begin
20: CenterY := CurToken.FloatValue; 20: CenterY := CurToken.FloatValue;
30: CenterZ := CurToken.FloatValue; 30: CenterZ := CurToken.FloatValue;
40: Radius := CurToken.FloatValue; 40: Radius := CurToken.FloatValue;
50: StartAngle := CurToken.FloatValue;
51: EndAngle := CurToken.FloatValue;
end; end;
end; end;

View File

@ -139,6 +139,7 @@ type
TvCircularArc = class(TvEntity) TvCircularArc = class(TvEntity)
public public
CenterX, CenterY, CenterZ, Radius: Double; CenterX, CenterY, CenterZ, Radius: Double;
{@@ The Angle is measured in degrees in relation to the positive X axis }
StartAngle, EndAngle: Double; StartAngle, EndAngle: Double;
end; end;
@ -151,7 +152,7 @@ type
public public
// Mandatory fields // Mandatory fields
CenterX, CenterY, CenterZ, MajorHalfAxis, MinorHalfAxis: Double; 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; Angle: Double;
// Calculated fields // Calculated fields
BoundingRect: TRect; BoundingRect: TRect;

View File

@ -4,17 +4,28 @@ unit fpvtocanvas;
interface interface
{$define USE_LCL_CANVAS}
uses uses
Classes, SysUtils, Classes, SysUtils, Math,
{$ifdef USE_LCL_CANVAS}
Graphics, LCLIntf,
{$else}
fpcanvas, fpcanvas,
{$endif}
fpvectorial; 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); ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
implementation implementation
{function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint; function Rotate2DPoint(P,Fix :TPoint; alpha:double): TPoint;
var var
sinus, cosinus : Extended; sinus, cosinus : Extended;
begin begin
@ -23,31 +34,46 @@ begin
P.y := P.y - Fix.y; P.y := P.y - Fix.y;
result.x := Round(p.x*cosinus + p.y*sinus) + fix.x ; result.x := Round(p.x*cosinus + p.y*sinus) + fix.x ;
result.y := Round(-p.x*sinus + p.y*cosinus) + Fix.y; result.y := Round(-p.x*sinus + p.y*cosinus) + Fix.y;
end;} end;
procedure DrawRotatedEllipse(ADest: TFPCustomCanvas; CurEllipse: TvEllipse); procedure DrawRotatedEllipse(
{var {$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; PointList: array[0..6] of TPoint;
f: TPoint; f: TPoint;
dk: Integer;} dk, x1, x2, y1, y2: Integer;
begin begin
{ dk := Round(0.654 * Abs(y2-y1)); {$ifdef USE_LCL_CANVAS}
f.x := CurEllipse.CenterX; CurEllipse.CalculateBoundingRectangle();
f.y := CurEllipse.CenterY - 1; x1 := CurEllipse.BoundingRect.Left;
PointList[0] := Rotate2DPoint(Point(x1, f.y), f, Alpha) ; // Startpoint x2 := CurEllipse.BoundingRect.Right;
PointList[1] := Rotate2DPoint(Point(x1, f.y - dk), f, Alpha); 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 //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 //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 // 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 // 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 // Conrollpoint of secondpart endpoint
PointList[6] := PointList[0]; // Endpoint of PointList[6] := PointList[0]; // Endpoint of
// Back to the startpoint // Back to the startpoint
PolyBezier(canvas.handle, Pointlist[0], 7);} ADest.PolyBezier(Pointlist[0]);
{$endif}
end; end;
{@@ {@@
@ -64,7 +90,12 @@ end;
DrawFPVectorialToCanvas(ASource, ADest, 0, ASource.Height, 1.0, -1.0); 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); ADestX: Integer = 0; ADestY: Integer = 0; AMulX: Double = 1.0; AMulY: Double = 1.0);
var var
i, j, k: Integer; i, j, k: Integer;
@ -80,7 +111,7 @@ var
CurEntity: TvEntity; CurEntity: TvEntity;
CurCircle: TvCircle; CurCircle: TvCircle;
CurEllipse: TvEllipse; CurEllipse: TvEllipse;
CurCircularArc: TvCircularArc; CurArc: TvCircularArc;
begin begin
{$ifdef FPVECTORIALDEBUG} {$ifdef FPVECTORIALDEBUG}
WriteLn(':>DrawFPVectorialToCanvas'); WriteLn(':>DrawFPVectorialToCanvas');
@ -161,8 +192,18 @@ begin
end end
else if CurEntity is TvCircularArc then else if CurEntity is TvCircularArc then
begin begin
CurCircularArc := CurEntity as TvCircularArc; CurArc := CurEntity as TvCircularArc;
// ADest.Arc(ADest, CurEllipse); {$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;
end; end;

View File

@ -7,7 +7,6 @@
<MainUnit Value="0"/> <MainUnit Value="0"/>
<ResourceType Value="res"/> <ResourceType Value="res"/>
<UseXPManifest Value="True"/> <UseXPManifest Value="True"/>
<Icon Value="0"/>
</General> </General>
<i18n> <i18n>
<EnableI18N LFM="False"/> <EnableI18N LFM="False"/>