2011-11-30 4 views
5

enter image description hereL'intersezione della retta e dei lati del triangolo

I punti obbligatori sono rossi. Io disegno ciò usando delphi.

with Image1.Canvas do 
begin 
Image1.Canvas.Pen.Color :=RGB(255,0,0); 
    MoveTo(30,3); // 1 
    LineTo(260,10);// 1-2 
    LineTo(100,100);//2-3 
    LineTo(30,3);//3-1 
Image1.Canvas.Pen.Color :=RGB(0,0,255); 
    MoveTo(20,80);//4 
    LineTo(300,40);//4-5 

end; 
+0

Vuoi conoscere le corde dell'intersezione? O vuoi semplicemente riempire le regioni secondo la risposta di TOndrej? –

+0

[Date un'occhiata a questo] (http://delphiforfun.org/programs/math_topics/intersecting_lines.htm), potrebbe darvi un'idea di come procedere. – Shirish11

+1

@DavidHeffernan Il codice nella mia risposta non è _giusto riempire regioni_. Determina le coordinate ('Pt1',' Pt2'). Riempire le regioni è lì solo per mostrare un feedback visivo. –

risposta

13

Dal momento che si sta già utilizzando GDI (Canvas), è possibile utilizzare anche le regioni, ecco un esempio:

procedure TForm1.PaintBox1Paint(Sender: TObject); 
var 
    Canvas: TCanvas; 
    T1, T2: array[0..2] of TPoint; 
    R1, R2: HRGN; 
    Buffer: PRgnData; 
    BufferSize: Cardinal; 
    P: PRect; 
    I: Integer; 
    Pt1, Pt2: TPoint; // result intersection points 
begin 
    Canvas := (Sender as TPaintBox).Canvas; 

    // first triangle region 
    T1[0] := Point(100, 100); 
    T1[1] := Point(260, 10); 
    T1[2] := Point(30, 3); 
    R1 := CreatePolygonRgn(T1[0], 3, ALTERNATE); 
    if R1 = 0 then 
    RaiseLastOSError; 
    try 
    // show the first triangle as red (not needed for computation) 
    Canvas.Brush.Color := clRed; 
    FillRgn(Canvas.Handle, R1, Canvas.Brush.Handle); 

    // second triangle region  
    T2[0] := Point(20, 80); 
    T2[1] := Point(300, 40); 
    T2[2] := Point(100, 100); 
    R2 := CreatePolygonRgn(T2[0], 3, ALTERNATE); 
    if R2 = 0 then 
     RaiseLastOSError; 
    try 
     // show the second triangle as green (not needed for computation) 
     Canvas.Brush.Color := clGreen; 
     FillRgn(Canvas.Handle, R2, Canvas.Brush.Handle); 

     // determine the intersecting region  
     if CombineRgn(R1, R1, R2, RGN_AND) = ERROR then 
     RaiseLastOSError; 
     // show intersection as yellow (not needed for computation) 
     Canvas.Brush.Color := clYellow; 
     FillRgn(Canvas.Handle, R1, Canvas.Brush.Handle); 

     // determine the needed buffer size  
     Buffer := nil; 
     BufferSize := GetRegionData(R1, 0, Buffer); 
     // allocate buffer and get region data (array of rectangles) 
     Buffer := AllocMem(BufferSize); 
     try 
     if GetRegionData(R1, BufferSize, Buffer) = 0 then 
      RaiseLastOSError; 

     // enumerate all rectangles and find points with leftmost and rightmost X  
     P := @Buffer^.Buffer[0]; 
     Pt1 := P^.TopLeft; 
     Pt2 := Point(P^.Right, P^.Top); 
     for I := 0 to Buffer^.rdh.nCount - 1 do 
     begin 
      if P^.Left < Pt1.X then 
      Pt1 := P^.TopLeft; 
      if P^.Right > Pt2.X then 
      Pt2 := Point(P^.Right, P^.Top); 
      Inc(P); 
     end; 

     // connect the points with a blue line (not needed for computation) 
     Canvas.Pen.Color := clNavy; 
     Canvas.MoveTo(Pt1.X, Pt1.Y); 
     Canvas.LineTo(Pt2.X, Pt2.Y); 

     // output result points (not needed for computation)  
     Canvas.Brush.Color := Self.Color; 
     Canvas.Font.Color := clWindowText; 
     Canvas.TextOut(8, 108, Format('Pt1: %d, %d, Pt2: %d, %d', [Pt1.X, Pt1.Y, Pt2.X, Pt2.Y])); 
     finally 
     FreeMem(Buffer); 
     end; 
    finally 
     DeleteObject(R2); 
    end; 
    finally 
    DeleteObject(R1); 
    end; 
end; 

Questo produrrà il seguente risultato:

Screenshot

Problemi correlati