Non esiste una funzione built-in per questo.
Ma quello che penso tu stia cercando di fare è questo:
Dato un poligono (noto anche come TPath) composto per punti distinti collegati da linee.
Restituisce tutti i punti in ShapeA che si trovano all'interno di ShapeB.
punto di intersezione
questo può essere fatto utilizzando PointInObjectLocal
.
Esegui un ciclo visitando tutti i punti in PathA
e verifica se c'è spazio all'interno di PathB
.
linea di intersezione
Se volete conoscere tutti i vertici che si sovrappongono per prima cosa devi Flatten
(una copia) di entrambi TPaths e quindi eseguire una linea interseca algoritmo per tutte le linee in entrambe le forme.
Converte tutte le curve in linee.
Ecco una routine per fare proprio questo:
Da: http://www.partow.net/projects/fastgeo/index.html
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;
solo convertire i TFloat
coppie x, y per TPointF
e siete a posto. La cosa bella della routine è che ti dice anche il punto esatto in cui le linee si sovrappongono.
Se si seguono le linee, fino a quando due linee si sovrappongono e da lì in poi si esegue il tracciamento di entrambe le linee sovrapposte e PointInShape è possibile costruire un'immagine esatta della sovrapposizione delle due forme.
rendendo più veloce
Se l'appiattimento e il corrispondente aumento del numero di segmenti di linea rendono il codice troppo lento è possibile mantenere le curve e vedere se una linea/curva interseca un'altra curva.
Per questo è possibile convertire le curve in bezier curves e utilizzare De_Casteljau's algorithm
Maggiori informazioni
Vedi anche this question e il link to Delphi source code nella sua prima o seconda risposta.
Mi piace la domanda, ma la prossima volta, includi una foto di ciò che stai cercando di ottenere, vedi: http://stackoverflow.com/questions/3940694/line-clipping-to-arbitary-2d-polygon per un esempio di uso efficace della grafica in una domanda. – Johan