Draw a marker like google maps from TCanvas to Delphi

In my application, I need to draw a “marker” on a TCanvas, for example, a Google Maps marker (see image).

google marker

I would like to use the radius, height and origin as parameters:

marker parameters

I have no idea about using an algorithm. I can use the arc to draw the top, but how to draw the bottom? Note. I need to use it with both GDI and GDI +, so any solution is welcome.

+6
source share
1 answer

Here is a quick example using 200x200 PaintBox - it should at least give you an idea of ​​the algorithm. Hope you can draw a black dot in the middle. Read on Bezier Curves ; PolyBezier defines cubic Bezier curves. (link)

bezier

Four points define a cubic Bezier curve — a start, an end, and two control points. The control points determine the strength of the curvature when the line moves from beginning to end.

 var origin, innerL, midL, midR, lft, tp, rgt, innerR : TPoint; radius, hgt : integer; begin radius := 25; hgt := 90; origin.X := 100; origin.Y := 180; //control points innerL.X := origin.X; innerL.Y := origin.Y - (hgt - radius) div 3; midL.X := origin.X - radius; midL.Y := origin.Y - 2*((hgt - radius) div 3); //top circle lft.X := origin.X - radius; lft.Y := origin.Y - (hgt - radius); tp.X := origin.X; tp.Y := origin.Y - hgt; rgt.X := origin.X + radius; rgt.Y := lft.Y; //control points midR.X := origin.X + radius; midR.Y := midL.Y; innerR.X := origin.X; innerR.Y := innerL.Y; PaintBox1.Canvas.Pen.Width := 2; PaintBox1.Canvas.PolyBezier([origin, innerL, midL, lft]); PaintBox1.Canvas.Arc(lft.X, tp.Y, rgt.X, rgt.Y + radius, rgt.X, rgt.Y, lft.X, lft.Y); PaintBox1.Canvas.PolyBezier([rgt, midR, innerR, origin]); //fill PaintBox1.Canvas.Brush.Color := clYellow; PaintBox1.Canvas.FloodFill(origin.X, origin.Y - radius, Canvas.Pen.Color, TFillStyle.fsBorder); end; 

To satisfy the fact that you can do this with one bezier:

  // add four more control TPoints cornerL.X := lft.X; cornerL.Y := tp.Y + radius div 2; cL2.X := lft.X + radius div 2; cL2.Y := tp.Y; cR2.X := rgt.X - radius div 2; cR2.Y := tp.Y; cornerR.X := rgt.X; cornerR.Y := cornerL.Y; PaintBox1.Canvas.PolyBezier([origin, innerL, midL, lft, cornerL, cL2, tp, cR2, cornerR, rgt, midR, innerR, origin]); 
+10
source

Source: https://habr.com/ru/post/952125/


All Articles