2015-06-16 20 views
11

Herkes, iki TShapes için kesişim TPath'ı döndüren bir işlev hakkında bilgi sahibi mi? Özellikle iki TPath'ın kesişim TPath'ı döndüren biri. ÖrneğinTPaths dahil iki TShapes'in kesişimini döndüren işlev?

:

pthIntersection := PathIntersection(Path1,Path2); 

enter image description here

+0

Soruyu beğeniyorum, ama bir dahaki sefere, lütfen elde etmeye çalıştığınız şeyin bir resmini ekleyin, bkz: http://stackoverflow.com/questions/3940694/line-clipping-to-arbitary-2d-polygon Bir sorudaki grafiklerin etkili kullanımının bir örneği. – Johan

cevap

14

bunun için yerleşik bir işlevi yoktur.
Ama yapmaya çalıştığım şey şu:

Çizgilerle birbirine bağlanan farklı noktalardan oluşan bir poligon (aka TPath) verildi.
ShapeB içinde yer alan ShapeA'daki tüm noktaları döndür.

Noktası kesişme
Bu PointInObjectLocal kullanılarak yapılabilir.
PathA'daki tüm noktaları ziyaret ederek bir döngüyü çalıştırın ve PathB'un içine girip girmediğini görün.

Çizgi kesişim
Eğer ilk olarak her iki TPaths ait Flatten (kopya) gerekecek örtüşen tüm köşeleri bilmek ve sonra bir satır, her iki şekil de tüm hatlar için algoritma kesiştiği çalıştırmak istiyorsanız

.
Bu, tüm eğrileri çizgiye dönüştürür.

function Intersect(const x1, y1, x2, y2, x3, y3, x4, y4: TFloat; out ix, iy: TFloat): boolean; 
var 
    UpperX, UpperY, LowerX, LowerY: TFloat; 
    Ax, Bx, Cx, Ay, By, Cy: TFloat; 
    D, F, E, Ratio: TFloat; 
begin 
    Result:= false; 

    Ax:= x2 - x1; 
    Bx:= x3 - x4; 

    if Ax < Zero then begin 
    LowerX:= x2; 
    UpperX:= x1; 
    end else begin 
    UpperX:= x2; 
    LowerX:= x1; 
    end; 

    if Bx > Zero then begin 
    if (UpperX < x4) or (x3 < LowerX) then Exit; 
    end else if (UpperX < x3) or (x4 < LowerX) then Exit; 

    Ay:= y2 - y1; 
    By:= y3 - y4; 

    if Ay < Zero then begin 
    LowerY:= y2; 
    UpperY:= y1; 
    end else begin 
    UpperY:= y2; 
    LowerY:= y1; 
    end; 

    if By > Zero then begin 
    if (UpperY < y4) or (y3 < LowerY) then Exit; 
    end else if (UpperY < y3) or (y4 < LowerY) then Exit; 

    Cx:= x1 - x3; 
    Cy:= y1 - y3; 
    D:= (By * Cx) - (Bx * Cy); 
    F:= (Ay * Bx) - (Ax * By); 

    if F > Zero then begin 
    if (D < Zero) or (D > F) then Exit; 
    end else if (D > Zero) or (D < F) then Exit; 

    E:= (Ax * Cy) - (Ay * Cx); 

    if F > Zero then begin 
    if (E < Zero) or (E > F) then Exit; 
    end else if (E > Zero) or (E < F) then Exit; 

    Result:= true; 

    Ratio:= (Ax * -By) - (Ay * -Bx); 

    if NotEqual(Ratio, Zero) then begin 
    Ratio:= ((Cy * -Bx) - (Cx * -By))/Ratio; 
    ix:= x1 + (Ratio * Ax); 
    iy:= y1 + (Ratio * Ay); 
    end else begin 
    //if Collinear(x1,y1,x2,y2,x3,y3) then 
    if IsEqual((Ax * -Cy), (-Cx * Ay)) then begin 
     ix:= x3; 
     iy:= y3; 
    end else begin 
     ix:= x4; 
     iy:= y4; 
    end; 
    end; 
end; 

function Intersect(const Segment1,Segment2:TSegment2D; out ix, iy : TFloat):Boolean; 
begin 
    Result := Intersect(Segment1[1].x,Segment1[1].y,Segment1[2].x,Segment1[2].y,Segment2[1].x,Segment2[1].y,Segment2[2].x,Segment2[2].y,ix,iy); 
end; 

http://www.partow.net/projects/fastgeo/index.html Sadece TPointF için TFloat x, y çiftleri dönüştürmek ve iş demektir:
Gönderen:

İşte tam da bunu yapmak için rutin bir şey. Rutin hakkında harika olan şey, aynı zamanda çizgilerin üst üste geldiği noktayı size bildirmesidir.

Satırları takip ederseniz, iki çizgi üst üste gelene kadar üst üste biner ve oradan üst üste binen çizgileri ve PointInShape'ı izlemeye başlarsanız, iki şeklin üst üste binmesinin tam bir görüntüsünü oluşturabilirsiniz.

düzleşme ve çizgi segmentlerinin sayısında gelen artış, kod de seni eğrileri tutmak ve bir çizgi/eğri başka eğri kesiştiğini görebilirsiniz yavaş yapmak daha hızlı
ise yapma. Bunun için
Eğer bezier curves içine eğrileri dönüştürmek ve De_Casteljau's algorithm

Daha da bilgi
bakın this question ve ilk veya ikinci yanıtında link to Delphi source code kullanabilirsiniz.

+1

Dankie, Johan. Korktuğum için zor yoldan gitmem gerekti ve hiç kimse bir TPath çözümü ile gelmedikten sonra o yol boyunca başladım (hiç amaçlanmadı). Sorunum çoğunlukla bezier eğrileriyle ilgiliyse, ben de bağlantılara bakacağım. – Domus

İlgili konular