2013-08-20 60 views
6

Uygulamamda, Google Maps marker gibi ("resme bakın") TCanvas üzerinde bir "işaretçiyi" çizmem gerekiyor.Delphi üzerinde TCanvas ile google maps gibi bir işaretçi çizin

google marker

yarıçapı, boy ve kökenini parametreleri gibi kullanılmasını istiyorum:

marker parameters

Kullanmak algoritması hakkında fikrim yok. Tepeyi çizmek için bir yay kullanabilirim ama nasıl alt çizebilirim? Not: Her ikisini de GDI ve GDI + ile çizmem gerekiyor.

+2

Kaba olmak istemiyorum, ama bu Delphi veya GDI bir ilgisi var sanmıyorum özellikle. Daha çok, üç parametre alan ve yukarıdaki gibi bir şey çıkaran bir algoritma aramak gibi. –

+0

@ GünthertheBeautiful mümkün ama bunu GDI ve GDI + – Martin

+1

kullanarak Delphi ile yapmam gerekiyor. Önemli olan matematiksel açıklamaya sahip olduğunuzda, dilediğiniz herhangi bir dilde çizebilirsiniz. Bu kategorik olarak delphi bir soru değil. FWIW Ben google raster görüntüleri kullanın bahse girerim. –

cevap

10

200x200 PaintBox kullanarak hızlı bir örnek - en azından algoritma için bir fikir vermelidir. Eminim ortadaki siyah noktayı çizebilirsin. Bezier Curves'da okuyun; başlangıç ​​uç ve iki kontrol noktası - PolyBeziercubic Bezier curves. (link)

bezier

dört noktaları bir Bezier eğriyi tanımlayan tanımlar. Kontrol noktaları, hat baştan sona ilerledikçe eğriliğin mukavemetini tanımlar.

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; 

tek Bezier ile yapabilirsiniz noktayı tatmin etmek için:

// 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]); 
+4

"FloodFill" eski gönderimine gerek yoktur. Ayrıca, tüm işaretleyici şeklini bezier eğrileriyle tanımlayabilirsiniz (ve bunu bir "PolyBezier" çağrısıyla çizebilirsiniz). – TLama

+2

@TLama - evet, bunu tek bir bezerle yapabilirsin. Hızla yaptım ve dört tane daha kontrol noktası tanımlamak istemedim - didaktik olması, üretimin tamamlanmış olması gerekiyordu. Ark kodu daha hızlıydı, daha iyi değil. Açıkçası, bir GDI çözümü, yolları (aynı şekilde Beziers'i tanımlayan) yollar kullanacaktı ve yollarla doldurma gerekmediğini, doğal olarak. Yine, OP'nin işi onun için yapmaya çalışmamak, nasıl bir bezemeciydi. –

+1

Evet, daha iyisi :-) Ve haklısın. GDI + ile bir yol oluşturabilir ve yolu doldurabilirsiniz. Orada daha kolay. [+1] – TLama