在我的应用程序中,我需要在TCanvas上绘制一个“标记”,如谷歌地图标记(见图).
我想用作半径,高度和原点的参数:
我不知道要使用的算法.我可以使用弧线绘制顶部,但我如何绘制底部?
注意:我需要用GDI和GDI绘制它,所以欢迎任何解决方案.
解决方法
这是一个使用200×200 PaintBox的快速示例 – 它至少应该为您提供算法的想法.我相信你可以在中间画出黑点.阅读
Bezier Curves; PolyBezier定义了
cubic Bezier curves. (link)
四个点定义了一个三次贝塞尔曲线 – 起点,终点和两个控制点.当线从开始移动到结束时,控制点定义曲率的强度.
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,lft]); PaintBox1.Canvas.Arc(lft.X,tp.Y,rgt.X,rgt.Y + radius,rgt.Y,lft.X,lft.Y); PaintBox1.Canvas.PolyBezier([rgt,innerR,origin]); //fill PaintBox1.Canvas.Brush.Color := clYellow; PaintBox1.Canvas.FloodFill(origin.X,origin.Y - radius,Canvas.Pen.Color,TFillStyle.fsBorder); end;
为了满足您可以使用一个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,cornerL,cL2,cR2,cornerR,origin]);