在Delphi上用TCanvas绘制一个像google地图的标记 [英] Draw a marker like google maps with TCanvas on Delphi
问题描述
我想使用半径,高度和起点的参数:
我不知道使用算法。我可以使用弧线来绘制顶部,但是如何绘制底部?
注意:我需要使用GDI和GDI +绘制,所以任何解决方案都是受欢迎的。
例如使用200x200 PaintBox
- 它至少应该给你一个算法的想法。我相信你可以画中间的黑点。阅读贝塞尔曲线; PolyBezier
定义了 <贝司曲线。 (链接)
四点定义一个立方贝塞尔曲线 - 开始,结束和两个控制点。控制点定义曲线随着线从头到尾移动的强度。
var origin,innerL,midL,midR,lft,tp,rgt,innerR:TPoint;
radius,hgt:integer;
begin
radius:= 25;
hgt:= 90;
origin.X:= 100;
origin.Y:= 180;
//控制点
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);
//顶圈
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;
//控制点
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);
结束
要满足您可以使用一个贝塞尔语:
//添加另外四个控件TPoint
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 ,来源]);
On my application I need draw on TCanvas a "marker", like Google Maps marker (see the image).
I'd like use as parameters the radius, the height and the origin:
I don't have idea about algorithm to use. I can use an arc to draw the top, but how can I draw the bottom? Note: I need draw it both with GDI and GDI+ so any solution is welcome.
Here is a quick example using a 200x200 PaintBox
- it should at least give you an idea for the algorithm. I trust you can draw the black dot in the middle. Read up on Bezier Curves; PolyBezier
defines cubic Bezier curves. (link)
Four points define a cubic Bezier curve - start, end, and two control points. Control points define the strength of curvature as the line moves from start 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 point 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]);
这篇关于在Delphi上用TCanvas绘制一个像google地图的标记的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!