{$N+} { Intersectii intre drepte, segmente; Dreapta ce trece prin doua puncte date; Segmentul dat de extremitatile sale. } unit IntersDr; interface uses Types; (*----------------------------------------------------------------*) function poz_punct_dr(var d: Dreapta; var p: TPunct): integer; function poz_punct_vec(var v: Segment; var p: TPunct): integer; function dr_of_puncte (var d: Dreapta; var p1, p2: TPunct): boolean; {Creaza dreapta ce trece prin p1 si p2} function dr_of_segment(var d: Dreapta; var s: Segment): boolean; {Creaza dreapta ce contine segmentul s} function inters_dr(d1, d2: Dreapta; var p: TPunct): RelDrepte; (* Lab 2, Var 1 *) function inters_dr_seg(d: Dreapta; s: Segment; var p: TPunct): RelDrepte; (* Lab 2, Var 2 *) function inters_seg_seg(var a, b: Segment; var p: TPunct): RelDrepte; (* Lab 2, Var 3 *) function se_inters_seg_seg(var a, b: Segment): boolean; (* Lab 2, Var 4 *) (*----------------------------------------------------------------*) (*----------------------------------------------------------------*) implementation uses Punct; (*----------------------------------------------------------------*) (* Lab 2, Var 1 *) (*----------------------------------------------------------------*) function inters_dr(d1, d2: Dreapta; var p: TPunct): RelDrepte; var dt: TCoord; begin if( d1.A*d2.B = d1.B*d2.A ) then begin if( d1.A*d2.C = d1.C*d2.A ) then inters_dr := incident else inters_dr := vid; end else begin dt := (d1.A*d2.B - d1.B*d2.A) ; p.x := (d1.C*d2.B - d1.B*d2.C) / dt; p.y := (d1.A*d2.C - d1.C*d2.A) / dt; inters_dr := inters; end; end; { A d dx dy A1 B1 C1 A1 B1 C1 B1 A1 C1 A2 B2 C2 A2 B2 C2 B2 A2 C2 } (*----------------------------------------------------------------*) (* Lab 2, Var 2 *) (*----------------------------------------------------------------*) function inters_dr_seg(d: Dreapta; s: Segment; var p: TPunct): RelDrepte; var i,j,k: integer; d2: Dreapta; dt: TCoord; begin i := poz_punct_dr(d, s.p1); j := poz_punct_dr(d, s.p2); k := i*j; if( k = 0 )then begin inters_dr_seg := inters; if(i <> 0)then p := s.p2 else (* s.p2 este punctul de intersectie *) if(j <> 0)then p := s.p1 else (* s.p1 este punctul de intersectie *) inters_dr_seg := incident; (* segmentul se afla pe dreapta *) end else if( k > 0 ) then (* p1 si p2 sunt de aceeasi parte a d *) inters_dr_seg := vid (* dreapta si segmentul nu se intersecteaza *) else (* k < 0 => p1 si p2 sunt de parti diferite a d *) if( not dr_of_segment(d2, s) ) then inters_dr_seg := nedet else begin dt := (d.A*d2.B - d.B*d2.A) ; p.x := (d.C*d2.B - d.B*d2.C) / dt; p.y := (d.A*d2.C - d.C*d2.A) / dt; inters_dr_seg := inters; end; end; (*----------------------------------------------------------------*) function dr_of_puncte (var d: Dreapta; var p1, p2: TPunct): boolean; begin dr_of_puncte := false; if(p1.x = p2.x) and (p1.y = p2.y) then exit; { Exista o infinitate de drepte :-( } d.A := p2.y - p1.y; d.B := p1.x - p2.x; d.C := p2.x*p1.y - p1.x*p2.y; dr_of_puncte := true; { Success! :-) } end; (*----------------------------------------------------------------*) function dr_of_segment(var d: Dreapta; var s: Segment): boolean; begin dr_of_segment := dr_of_puncte(d, s.p1, s.p2) end; (*----------------------------------------------------------------*) (* Lab 2, Var 3 *) (*----------------------------------------------------------------*) function inters_seg_seg(var a, b: Segment; var p: TPunct): RelDrepte; var d1, d2: Dreapta; dt: TCoord; begin if( poz_punct_vec(a, b.p1) * poz_punct_vec(a, b.p2) <= 0 ) and ( poz_punct_vec(b, a.p1) * poz_punct_vec(b, a.p2) <= 0 ) then begin inters_seg_seg := nedet; if( not dr_of_segment(d1, a) ) then exit; if( not dr_of_segment(d2, b) ) then exit; dt := (d1.A*d2.B - d1.B*d2.A) ; if(dt <> 0)then begin {Segmentele nu sunt pe aceeasi dreapta} p.x := (d1.C*d2.B - d1.B*d2.C) / dt; p.y := (d1.A*d2.C - d1.C*d2.A) / dt; end else begin {Segmentele sunt pe aceeasi dreapta} {Determinam care punct se afla pe segment} if(in_patrat(a.p1, b.p1, b.p2)) then p := a.p1 else if(in_patrat(a.p2, b.p1, b.p2)) then p := a.p2 else if(in_patrat(b.p1, a.p1, a.p2)) then p := b.p1 else p := b.p2 ; end; inters_seg_seg := inters; end else inters_seg_seg := vid; end; (*----------------------------------------------------------------*) (* Lab 2, Var 4 *) (*----------------------------------------------------------------*) function se_inters_seg_seg(var a, b: Segment): boolean; begin se_inters_seg_seg := ( poz_punct_vec(a, b.p1) * poz_punct_vec(a, b.p2) <= 0 ) and ( poz_punct_vec(b, a.p1) * poz_punct_vec(b, a.p2) <= 0 ) ; end; (*----------------------------------------------------------------*) function poz_punct_vec(var v: Segment; var p: TPunct): integer; begin poz_punct_vec := trunc(sarrus(v.p1, v.p2, p)); end; function poz_punct_dr(var d: Dreapta; var p: TPunct): integer; begin poz_punct_dr := trunc(d.A*p.x + d.B*p.y + d.C); end; (*----------------------------------------------------------------*) end.