//
unit ads_Canvas; {Copyright(c)2016 Advanced Delphi Systems Richard Maley Advanced Delphi Systems 12613 Maidens Bower Drive Potomac, MD 20854 USA phone 301-840-1554 dickmaley@advdelphisys.com The code herein can be used or modified by anyone. Please retain references to Richard Maley at Advanced Delphi Systems. If you make improvements to the code please send your improvements to dickmaley@advdelphisys.com so that the entire Delphi community can benefit. All comments are welcome. } (*UnitIndex Master Index Implementation Section Download Units
Description: ads_Canvas.pas This unit contains the following routines.
Circle_1 Circle_2 Circle_3 DistanceFromAxis DistanceTweenPoints Ellipse EllipseDrawHalf G0DistanceOnLine_1 G0DistanceOnLine_2 GetEllipseHalfChord GetEllipsePoint Heart MarkPoint
*) interface Uses Graphics, Dialogs, SysUtils,Windows, Math; procedure Heart( Canvas : TCanvas; Top : Integer; Left : Integer; Height : Integer; Width : Integer ); Function Ellipse( Canvas : TCanvas; Apogeex : Integer; Apogeey : Integer; Perigeex : Integer; Perigeey : Integer; Width : Integer; Fill : Boolean; FillColor : TColor; BorderColor : TColor): Boolean; Procedure Circle( Canvas : TCanvas; DiameterPt1 : TPoint; DiameterPt2 : TPoint; Fill : Boolean; FillColor : TColor; BorderColor : TColor); OverLoad; Procedure Circle( Canvas : TCanvas; Center : TPoint; Width : Extended; Fill : Boolean; FillColor : TColor; BorderColor : TColor); OverLoad; Procedure Circle( Canvas : TCanvas; DiameterPt1x: Integer; DiameterPt1y: Integer; DiameterPt2x: Integer; DiameterPt2y: Integer; Fill : Boolean; FillColor : TColor; BorderColor : TColor); OverLoad; Function EllipseDrawHalf( Canvas : TCanvas; Apogee : TPoint; Perigee : TPoint; Width : Extended; LeftHalf : Boolean): TPoint; Function G0DistanceOnLine(StartPoint : TPoint; Slope: Extended;Distance: Extended;Plusx:Boolean): TPoint;Overload; Function G0DistanceOnLine( StartPoint : TPoint; Distance : Extended; Angle : Extended): TPoint; OverLoad; Function DistanceFromAxis(CurrentPoint,FocusPoint: TPoint; Slope,a: Extended;Plusx:Boolean): TPoint; Function DistanceTweenPoints(Point1,Point2: TPoint): Extended; Procedure MarkPoint(Canvas : TCanvas;Point : TPoint); Function GetEllipseHalfChord( Length : Extended; Width : Extended; Section: Extended): Extended; Function GetEllipsePoint( AxisPt : TPoint; Length : Extended; Width : Extended; Section: Extended; Slope : Extended; ToLeft : Boolean): TPoint; implementation //Unit Description UnitIndex Master Index
Function G0DistanceOnLine(StartPoint : TPoint; Slope: Extended;Distance: Extended;Plusx:Boolean): TPoint; Var inCounter : Integer; Dist : Extended; NewPoint : TPoint; NewPointx : Extended; NewPointy : Extended; Intercept : Extended; Lowx : Extended; Highx : Extended; Curx : Extended; Quality : Extended; Begin NewPoint.x := StartPoint.x; NewPoint.y := StartPoint.y; If Distance = 0.0 Then Exit; If Plusx Then Begin Lowx := StartPoint.x; Highx := StartPoint.x+Distance; End Else Begin Lowx := StartPoint.x-Distance; Highx := StartPoint.x; End; Curx := Lowx+((Highx-Lowx)/2); Intercept := StartPoint.y-(Slope*StartPoint.x); If Slope <> 0 Then Begin For inCounter := 1 To 1000 Do Begin NewPointx := Curx; NewPointy := (Slope*NewPointx)+ Intercept; Dist := Sqrt( ((StartPoint.x-NewPointx)*(StartPoint.x-NewPointx))+ ((StartPoint.y-NewPointy)*(StartPoint.y-NewPointy))); Quality := (Abs(Distance-Dist)/Distance); If Quality < 0.00001 Then Begin NewPoint.x := StrToInt(FloatToStr(Int(NewPointx))); NewPoint.y := StrToInt(FloatToStr(Int(NewPointy))); Break; End; If Dist > Distance Then Begin If Plusx Then Highx := Curx Else Lowx := Curx; End Else Begin If Plusx Then Lowx := Curx Else Highx := Curx; End; Curx := Lowx+((Highx-Lowx)/2); End; End Else Begin If Plusx Then Begin Lowx := StartPoint.y; Highx := StartPoint.y+Distance; End Else Begin Lowx := StartPoint.y-Distance; Highx := StartPoint.y; End; Curx := Lowx+((Highx-Lowx)/2); For inCounter := 1 To 1000 Do Begin NewPointx := StartPoint.x; NewPointy := Curx; Dist := Sqrt( ((StartPoint.x-NewPointx)*(StartPoint.x-NewPointx))+ ((StartPoint.y-NewPointy)*(StartPoint.y-NewPointy))); Quality := (Abs(Distance-Dist)/Distance); If Quality < 0.00001 Then Begin NewPoint.x := StrToInt(FloatToStr(Int(NewPointx))); NewPoint.y := StrToInt(FloatToStr(Int(NewPointy))); Break; End; If Dist > Distance Then Begin If Plusx Then Highx := Curx Else Lowx := Curx; End Else Begin If Plusx Then Lowx := Curx Else Highx := Curx; End; Curx := Lowx+((Highx-Lowx)/2); End; End; Result := NewPoint; End; //Unit Description UnitIndex Master Index
Function Ellipse( Canvas : TCanvas; Apogeex : Integer; Apogeey : Integer; Perigeex : Integer; Perigeey : Integer; Width : Integer; Fill : Boolean; FillColor : TColor; BorderColor : TColor): Boolean; Var Apogee : TPoint; Perigee : TPoint; Temp1 : TPoint; Temp2 : TPoint; Center : TPoint; End1 : TPoint; End2 : TPoint; Begin Result := True; Try Apogee.x := Apogeex; Apogee.y := Apogeey; Perigee.x := Perigeex; Perigee.y := Perigeey; If Apogee.x > Perigee.x Then Begin Temp1 := Apogee; Temp2 := Perigee; Apogee := Temp2; Perigee:= Temp1; End; If Apogee.x > Perigee.x Then Center.x := ((Apogee.x - Perigee.x) div 2) + Perigee.x Else Center.x := ((Perigee.x - Apogee.x) div 2) + Apogee.x; If Apogee.y > Perigee.y Then Center.y := ((Apogee.y - Perigee.y) div 2) + Perigee.y Else Center.y := ((Perigee.y - Apogee.y) div 2) + Apogee.y; Canvas.Pen.Color := BorderColor; End1 := EllipseDrawHalf( Canvas , //Canvas : TCanvas; Apogee , //Apogee : TPoint; Perigee, //Perigee : TPoint; Width , //Width : Extended; True );//LeftHalf : Boolean); End2 := EllipseDrawHalf( Canvas , //Canvas : TCanvas; Apogee , //Apogee : TPoint; Perigee, //Perigee : TPoint; Width , //Width : Extended; False );//LeftHalf : Boolean); With Canvas Do Begin MoveTo(End1.x,End1.y); LineTo(Perigee.x,Perigee.y); LineTo(End2.x,End2.y); If Fill Then Begin Brush.Color := FillColor; FloodFill( center.x, center.y, BorderColor, fsBorder); End; Refresh; End; Except Result := False; End; End; //Unit Description UnitIndex Master Index
Function DistanceFromAxis(CurrentPoint,FocusPoint: TPoint; Slope,a: Extended;Plusx:Boolean): TPoint; Var AxisX : Extended; HalfChord : Extended; HafChord : Integer; rlSlope : Extended; Begin AxisX := DistanceTweenPoints(CurrentPoint,FocusPoint); HalfChord := sqrt( ((((2*a)+(AxisX*AxisX))*((2*a)+(AxisX*AxisX)))-(AxisX*AxisX)) ); HafChord := StrToInt(FloatToStr(Int(HalfChord))); If Slope = 0 Then Begin rlSlope := 1; End Else Begin rlSlope := -1/Slope; End; Result := G0DistanceOnLine( CurrentPoint, //StartPoint : TPoint; rlSlope , //Slope: Extended; HafChord , //Distance: Integer; PlusX );//Plusx:Boolean): TPoint; End; //Unit Description UnitIndex Master Index
Function DistanceTweenPoints(Point1,Point2: TPoint): Extended; Begin Try Result := sqrt( ((Point1.x-Point2.x)*(Point1.x-Point2.x)) + ((Point1.y-Point2.y)*(Point1.y-Point2.y))); Except Result := 0.00; End; End; //Unit Description UnitIndex Master Index
Procedure MarkPoint(Canvas : TCanvas;Point : TPoint); Begin With Canvas Do Begin MoveTo(Point.x,Point.y); LineTo(Point.x-5,Point.y); MoveTo(Point.x,Point.y); LineTo(Point.x+5,Point.y); MoveTo(Point.x,Point.y); LineTo(Point.x,Point.y-5); MoveTo(Point.x,Point.y); LineTo(Point.x,Point.y+5); End; End; //Unit Description UnitIndex Master Index
Function GetEllipseHalfChord( Length : Extended; Width : Extended; Section: Extended): Extended; Var a : Extended; b : Extended; x : Extended; xx : Extended; aa : Extended; bb : Extended; Begin Result := 0.0; a := Length/2; b := Width/2; If Section > Length Then Section := Length; If Section < 0.0 Then Section := 0.0; x := Section-a; xx := (x*x); aa := (a*a); bb := (b*b); If a = 0.0 Then Exit; Result := sqrt( (1-((xx)/(aa)))*(bb) ); End; //Unit Description UnitIndex Master Index
Function GetEllipsePoint( AxisPt : TPoint; Length : Extended; Width : Extended; Section: Extended; Slope : Extended; ToLeft : Boolean): TPoint; Var Dist : Extended; inDist : Integer; rlSlope: Extended; Begin Dist := GetEllipseHalfChord( Length , //Length : Extended; Width , //Width : Extended; Section);//Section: Extended): Extended; inDist := StrToInt(FloatToStr(Int(Dist))); If Slope = 0 Then Begin rlSlope := 1; End Else Begin rlSlope := -1/Slope; End; Result := G0DistanceOnLine( AxisPt , //StartPoint : TPoint; rlSlope , //Slope: Extended; inDist , //Distance: Integer; ToLeft );//Plusx:Boolean): TPoint; End; //Unit Description UnitIndex Master Index
Function EllipseDrawHalf( Canvas : TCanvas; Apogee : TPoint; Perigee : TPoint; Width : Extended; LeftHalf : Boolean): TPoint; Var Slope : Extended; LastAxis : TPoint; LastPoint : TPoint; CurAxis : TPoint; AxisDelta : Integer; AxisCum : Integer; NewPoint : TPoint; a : Extended; Length : Extended; Begin Result := Apogee; Length := DistanceTweenPoints(Apogee,Perigee); If Length = 0 Then Exit; If Width = 0 Then Exit; If (Apogee.x-Perigee.x) = 0.00 Then Slope := 999999.0 Else slope := (Apogee.y-Perigee.y)/(Apogee.x-Perigee.x); a := Length / 2; With Canvas Do Begin MoveTo(Apogee.x,Apogee.y); LastAxis := Apogee; LastPoint := Apogee; AxisDelta := 1; AxisCum := 0; While True Do Begin AxisCum := AxisCum + AxisDelta; If AxisCum > 2*a Then Begin CurAxis := Perigee; End Else Begin If (Abs(Slope) > 0) And (Abs(Slope) < 999999.0) Then Begin CurAxis := G0DistanceOnLine(Apogee,Slope,AxisCum,True); If LeftHalf Then NewPoint := GetEllipsePoint( CurAxis, //AxisPt : TPoint; 2*a , //Length : Extended; Width , //Width : Extended; AxisCum, //Section: Extended; Slope , //Slope : Extended; True )//ToLeft : Boolean): TPoint; Else NewPoint := GetEllipsePoint( CurAxis, //AxisPt : TPoint; 2*a , //Length : Extended; Width , //Width : Extended; AxisCum, //Section: Extended; Slope , //Slope : Extended; False );//ToLeft : Boolean): TPoint; End Else Begin If Slope = 0 Then Begin CurAxis := Apogee; CurAxis.x := Apogee.x+AxisCum; NewPoint := CurAxis; If LeftHalf Then NewPoint.y := NewPoint.y + StrToInt(FloatToStr(Int( GetEllipseHalfChord( 2*a, Width, AxisCum) ))) Else NewPoint.y := NewPoint.y - StrToInt(FloatToStr(Int( GetEllipseHalfChord( 2*a, Width, AxisCum) ))); End Else Begin CurAxis := Apogee; CurAxis.y := Apogee.y+AxisCum; NewPoint := CurAxis; If LeftHalf Then NewPoint.x := NewPoint.x + StrToInt(FloatToStr(Int( GetEllipseHalfChord( 2*a, Width, AxisCum) ))) Else NewPoint.x := NewPoint.x - StrToInt(FloatToStr(Int( GetEllipseHalfChord( 2*a, Width, AxisCum) ))); End; End; End; MoveTo(LastPoint.x,LastPoint.y); Result := LastPoint; LineTo(NewPoint.x,NewPoint.y); LastPoint := NewPoint; LastAxis := CurAxis; If AxisCum > 2*a Then Begin MoveTo(NewPoint.x,NewPoint.y); LineTo(Perigee.x,Perigee.y); If Slope = 0 Then Begin LineTo(Perigee.x,Perigee.y+3); LineTo(Perigee.x,Perigee.y-6); End Else Begin If Abs(Slope) > 9999 Then Begin LineTo(Perigee.x+3,Perigee.y); LineTo(Perigee.x-6,Perigee.y); End; End; Break; End; End; End; End; //Unit Description UnitIndex Master Index
procedure Heart( Canvas : TCanvas; Top : Integer; Left : Integer; Height : Integer; Width : Integer ); Var BoxLeftx : integer; BoxLefty : integer; BoxRightx : integer; BoxRighty : integer; ArcStartx : integer; ArcStarty : integer; ArcEndx : integer; ArcEndy : integer; begin Top := 100; Left := 100; Height := 300; Width := 100; With Canvas Do Begin BoxLeftx := Left+(width div 2); BoxLefty := Top; BoxRightx := Left+Width; BoxRighty := Top+Height; ArcStartx := BoxRightx; ArcStarty := Top+(Height div 2); ArcEndx := BoxLeftx; ArcEndy := ArcStarty; MoveTo(ArcStartx,ArcStarty); Arc( BoxLeftx, BoxLefty, BoxRightx, BoxRighty, ArcStartx, ArcStarty, ArcEndx, ArcEndy); BoxLeftx := Left; BoxLefty := Top; BoxRightx := Left+(Width div 2); BoxRighty := Top+Height; ArcStartx := BoxRightx; ArcStarty := Top+(Height div 2); ArcEndx := BoxLeftx; ArcEndy := ArcStarty; MoveTo(ArcStartx,ArcStarty); Arc( BoxLeftx, BoxLefty, BoxRightx, BoxRighty, ArcStartx, ArcStarty, ArcEndx, ArcEndy); BoxLeftx := Left-(17*Width); BoxLefty := Top-Height; BoxRightx := Left+Width; BoxRighty := Top+(Height*2); ArcStartx := Left+(Width div 2); ArcStarty := Top+Height-2; ArcEndx := Left+Width; ArcEndy := Top+(Height div 2); Arc( BoxLeftx, BoxLefty, BoxRightx, BoxRighty, ArcStartx, ArcStarty, ArcEndx, ArcEndy); BoxLeftx := Left; BoxLefty := Top-Height; BoxRightx := Left+Width+(17*Width); BoxRighty := Top+(Height*2); ArcStartx := Left; ArcStarty := Top+(Height div 2); ArcEndx := Left+(Width div 2); ArcEndy := Top+Height-2; Arc( BoxLeftx, BoxLefty, BoxRightx, BoxRighty, ArcStartx, ArcStarty, ArcEndx, ArcEndy); Brush.Color := clRed; FloodFill( Left+(width div 2), Top+height-(height div 4), clBlack, fsBorder); End; end; //Unit Description UnitIndex Master Index
Procedure Circle( Canvas : TCanvas; DiameterPt1 : TPoint; DiameterPt2 : TPoint; Fill : Boolean; FillColor : TColor; BorderColor : TColor); Var Width : Integer; Apogeex : Integer; Apogeey : Integer; Perigeex : Integer; Perigeey : Integer; Begin Width := StrToInt(FloatToStr(Int(DistanceTweenPoints(DiameterPt1,DiameterPt2)))); Apogeex := DiameterPt1.x; Apogeey := DiameterPt1.y; Perigeex := DiameterPt2.x; Perigeey := DiameterPt2.y; Ellipse( Canvas , //Canvas : TCanvas; Apogeex , //Apogeex : Integer; Apogeey , //Apogeey : Integer; Perigeex , //Perigeex : Integer; Perigeey , //Perigeey : Integer; Width , //Width : Integer; Fill , //Fill : Boolean; FillColor , //FillColor : TColor; BorderColor );//BorderColor : TColor): Boolean; End; //Unit Description UnitIndex Master Index
Procedure Circle( Canvas : TCanvas; DiameterPt1x: Integer; DiameterPt1y: Integer; DiameterPt2x: Integer; DiameterPt2y: Integer; Fill : Boolean; FillColor : TColor; BorderColor : TColor); OverLoad; Var DiameterPt1 : TPoint; DiameterPt2 : TPoint; Begin DiameterPt1.x := DiameterPt1x; DiameterPt1.y := DiameterPt1y; DiameterPt2.x := DiameterPt2x; DiameterPt2.y := DiameterPt2y; Circle( Canvas , //Canvas : TCanvas; DiameterPt1 , //DiameterPt1 : TPoint; DiameterPt2 , //DiameterPt2 : TPoint; Fill , //Fill : Boolean; FillColor , //FillColor : TColor; BorderColor );//BorderColor : TColor); End; //Unit Description UnitIndex Master Index
Procedure Circle( Canvas : TCanvas; Center : TPoint; Width : Extended; Fill : Boolean; FillColor : TColor; BorderColor : TColor); OverLoad; Var DiameterPt1 : TPoint; DiameterPt2 : TPoint; Radius : Extended; Begin Radius := Width/2; DiameterPt1 := G0DistanceOnLine( Center, //StartPoint : TPoint; 0 , //Slope : Extended; Radius, //Distance : Extended; False );//Plusx:Boolean): TPoint; DiameterPt2 := G0DistanceOnLine( Center, //StartPoint : TPoint; 0 , //Slope : Extended; Radius, //Distance : Extended; True );//Plusx:Boolean): TPoint; Circle( Canvas , //Canvas : TCanvas; DiameterPt1 , //DiameterPt1 : TPoint; DiameterPt2 , //DiameterPt2 : TPoint; Fill , //Fill : Boolean; FillColor , //FillColor : TColor; BorderColor );//BorderColor : TColor); End; //Unit Description UnitIndex Master Index
Function G0DistanceOnLine( StartPoint : TPoint; Distance : Extended; Angle : Extended): TPoint; OverLoad; Var Slope : Extended; Plusx : Boolean; Begin If (Angle >= (90-2)) And (Angle <= (90+2)) Then Begin Slope := 999; End Else Begin If (Angle >= (270-2)) And (Angle <= (270+2)) Then Begin Slope := 999; End Else Begin If Angle = 0.0 Then Begin Slope := 0.00001; End Else Begin Slope := Tan(Angle*(pi/180))*-1; End; End; End; Plusx := (((Angle >= 0 ) And (Angle < 90)) Or ((Angle > 270 ) And (Angle <= 360))); If (Angle >= (90-2)) And (Angle <= (90+2)) Then Plusx := False; If (Angle >= (270-2)) And (Angle <= (270+2)) Then Plusx := True; Result := G0DistanceOnLine( StartPoint, //StartPoint : TPoint; Slope , //Slope: Extended; Distance , //Distance: Extended; Plusx );//Plusx:Boolean): TPoint;Overload; End; end. //