///////////////////////////////////////////////////////////////////////
// Copyright (C) Andru 2007                                          //
// mail: dr.andru@gmail.com                                          //
// site: http://andru.2x4.ru                                         //
//                                                                   //
// OMEGA Engine is free software.                                    //
//                                                                   //
// You may redistribute it and/or modify it under the terms of the   //
// GNU General Public License, as published by the Free Software     //
// Foundation; either version 2 of the License, or (at your option)  //
// any later version.                                                //
//                                                                   //
// this module is distributed in the hope that it will be useful,    //
// but WITHOUT ANY WARRANTY; without even the implied warranty of    //
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.              //
// See the GNU General Public License for more details.              //
//                                                                   //
// You should have received a copy of the GNU General Public License //
// along with this module.  If not, write to:                        //
// 	The Free Software Foundation, Inc.,                              //
// 	51 Franklin Street, Fifth Floor                                  //
// 	Boston, MA  02110-1301, USA.                                     //
///////////////////////////////////////////////////////////////////////
unit COLLISION_MAIN;

{$I DEFINES.pas}

interface
uses
  Windows,
  G2D_PRIMITIVES,

  MATH_FAST,
  ENGINE_UTILS,
  UTILS;

type
  TPoint2D = oePoint;
  PPoint2D = oePPoint;

type
  TLine2D = oeLine;
  PLine2D = oePLine;

type
  TPolyLine2D = record
    Count  : DWORD;
    cX, cY : Single;
    Points : array of TPoint2D;
end;
PPolyLine2D = ^TPolyLine2D;

type
  TAABB2D = oeRect;
  PAABB2D = oePRect;

type
  TOBB2D = record
    X, Y   : Integer;
    Width  : Integer;
    Height : Integer;
    Angle  : Integer;
end;
POBB2D = ^TOBB2D;

type
  TCircle2D = oeCircle;
  PCircle2D = oePCircle;

// P O I N T ' s
function Col_PointInAABB    ( X, Y : Single; AABB : PAABB2D   ) : Boolean; stdcall;
function Col_PointInCircle  ( X, Y : Single; Circ : PCircle2D ) : Boolean; stdcall;
function Col_PointInPolyLine( X, Y : Single; PL : PPolyLine2D ) : Boolean; stdcall;
// L I N E ' s
function Col_Line          ( A, B : PLine2D ) : Boolean; stdcall;
function Col_LineVsAABB    ( A : PLine2D; AABB : PAABB2D ) : Boolean; stdcall;
function Col_LineVsCircle  ( L : PLine2D; Circ : PCircle2D ) : Boolean; stdcall;
function Col_LineVsCircleXY( L : PLine2D; Circ : PCircle2D; Precision : Integer ) : Boolean; stdcall;
function Col_LineVsPolyLine( A : PLine2D; B : PPolyLine2D ) : Boolean; stdcall;
// P O L Y L I N E ' s
function Col_PolyLine        ( A, B : PPolyLine2D ) : Boolean; stdcall;
function Col_PolyLineVsAABB  ( A : PPolyLine2D; AABB : PAABB2D ) : Boolean; stdcall;
function Col_PolyLineVsCircle( A : PPolyLine2D; Circ : PCircle2D ) : Boolean; stdcall;
function Col_PolyLineVsCircleXY( A : PPolyLine2D; Circ : PCircle2D; Precision : Integer ) : Boolean; stdcall;
// A A B B ' s
function Col_AABB        ( AABB1, AABB2 : PAABB2D ) : Boolean; stdcall;
function Col_AABBInAABB  ( AABB1, AABB2 : PAABB2D ) : Boolean; stdcall;
function Col_AABBInCircle( AABB : PAABB2D; Circ : PCircle2D ) : Boolean; stdcall;
function Col_AABBVsCircle( AABB : PAABB2D; Circ : PCircle2D ) : Boolean; stdcall;
// C I R C L E ' s
function Col_Circle        ( Circ1, Circ2 : PCircle2D ) : Boolean; stdcall;
function Col_CircleInCircle( Circ1, Circ2 : PCircle2D ) : Boolean; stdcall;
function Col_CircleInAABB  ( Circ : PCircle2D; AABB : PAABB2D ) : Boolean; stdcall;

// EXTENDED
// G E T ' s
function ColEx_LastX : Single; stdcall;
function ColEx_LastY : Single; stdcall;
function ColEx_LastLineA : Integer; stdcall;
function ColEx_LastLineB : Integer; stdcall;
// T R A N S F O R M A T I O N ' s
procedure ColEx_PolyRotate( A, B : PPolyLine2D; Angle : Single ); stdcall;
procedure ColEx_PolyScale( A : PPolyLine2D; ScaleX, ScaleY : Single ); stdcall;
procedure ColEx_PolyMove( A, B : PPolyLine2D; X, Y : Single ); stdcall;
procedure ColEx_PolyCenter( A : PPolyLine2D ); stdcall;
procedure ColEx_PolyRect( A : PPolyLine2D; Rect : PAABB2D ); stdcall;
// L I N E ' s
procedure ColEx_CalcLineCross( A, B : PLine2D ); stdcall;

//----------------------------------------------------------------------------//
                                 IMPLEMENTATION
//----------------------------------------------------------------------------//
var
  lX, lY   : Single;
  lS, lT   : Single;
  lLA, lLB : Integer;

function Dist( Ax, Ay, Bx, By, Cx, Cy : Single ) : Single;
  var
    dx, dy : Single;
    D      : Single;
Begin

dx := Ax - Bx;
dy := Ay - By;

D := dx * ( Cy - Ay ) - dy * ( Cx - Ax );

if D > 0 Then
  begin
    Result := D * D / ( dx * dx + dy * dy );
    Result := Result * Result;
  end else
    begin
      Result := D * D / ( dx * dx + dy * dy );
      Result := -Result * Result;
    end;
    
End;


// P O I N T ' s
function Col_PointInAABB;
Begin

if ( X > AABB^.X ) and ( X < AABB^.X + AABB^.Width  ) and
   ( Y > AABB^.Y ) and ( Y < AABB^.Y + AABB^.Height ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_PointInCircle;
Begin

if ( Circ^.cX - X ) * ( Circ^.cX - X ) +
   ( Circ^.cY - Y ) * ( Circ^.cY - Y ) <
   ( Circ^.Radius * Circ^.Radius ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_PointInPolyLine;
  var
    i : Integer;
Begin

Result := FALSE;
for i := 0 to PL^.Count - 1 do
  if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ i + 1 ].X, PL^.Points[ i + 1 ].Y, PL^.cX, PL^.cY  ) > 0 Then
    begin
      if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ i + 1 ].X, PL^.Points[ i + 1 ].Y, X, Y  ) < 0 Then
        exit;
    end else
      if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ i + 1 ].X, PL^.Points[ i + 1 ].Y, X, Y  ) > 0 Then
        exit;

if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ 0 ].X, PL^.Points[ 0 ].Y, PL^.cX, PL^.cY  ) > 0 Then
  begin
    if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ 0 ].X, PL^.Points[ 0 ].Y, X, Y  ) < 0 Then
      exit;
  end else
    if Dist( PL^.Points[ i ].X, PL^.Points[ i ].Y, PL^.Points[ 0 ].X, PL^.Points[ 0 ].Y, X, Y  ) > 0 Then
      exit;

Result := TRUE;

End;

// L I N E ' s
function Col_Line;
  var
    tmp    : Single;
    S1, S2 : array[ 0..1 ] of Single;
    s, t   : Single;
Begin

S1[ 0 ] := A^.x1 - A^.x0;
S1[ 1 ] := A^.y1 - A^.y0;
S2[ 0 ] := B^.x1 - B^.x0;
S2[ 1 ] := B^.y1 - B^.y0;

tmp := 1 / ( s2[ 0 ] * ( - S1[ 1 ] ) - ( - S1[ 0 ] ) * S2[ 1 ] );

s := ( ( A^.x0 - B^.x0 ) * ( - S1[ 1 ] ) - ( - S1[ 0 ] ) * ( A^.y0 - B^.y0 ) ) * tmp;
t := ( S2[ 0 ] * ( A^.y0 - B^.y0 ) - ( A^.x0 - B^.x0 ) * S2[ 1 ] ) * tmp;

if ( s >= 0 ) and ( s <= 1 ) and
   ( t >= 0 ) and ( t <= 1 ) Then
  Result := TRUE
else
  Result := FALSE;

lS := s;
lT := t;

End;

function Col_LineVsAABB;
  var
    L : TLine2D;
Begin

if Col_PointInAABB( A^.x0, A^.y0, AABB ) or Col_PointInAABB( A^.x1, A^.y1, AABB ) Then
  Result := TRUE
else
  begin
    L.x0 := AABB^.X;
    L.y0 := AABB^.Y;
    L.x1 := AABB^.X + AABB^.Width;
    L.y1 := AABB^.Y + AABB^.Height;
    if Col_Line( A, @L ) Then
      Result := TRUE
    else
      begin
        L.x0 := AABB^.X;
        L.y0 := AABB^.Y + AABB^.Height;
        L.x1 := AABB^.X + AABB^.Width;
        L.y1 := AABB^.Y;
        if Col_Line( A, @L ) Then Result := TRUE else Result := FALSE;
      end;
  end;

End;

function Col_LineVsCircle;
  var
    p1, p2  : array[ 0..1 ] of Single;
    dx, dy  : Single;
    a, b, c : Single;
Begin

p1[ 0 ] := L^.x0 - Circ^.cX;
p1[ 1 ] := L^.y0 - Circ^.cY;
p2[ 0 ] := L^.x1 - Circ^.cX;
p2[ 1 ] := L^.y1 - Circ^.cY;

dx := p2[ 0 ] - p1[ 0 ];
dy := p2[ 1 ] - p1[ 1 ];

a := dx * dx + dy * dy;
b := 2.0 * ( p1[ 0 ] * dx + p1[ 1 ] * dy );
c := p1[ 0 ] * p1[ 0 ] + p1[ 1 ] * p1[ 1 ] - Circ^.Radius * Circ^.Radius;

if -b < 0 Then
  Result := c < 0
else
  if -b < ( 2.0 * a ) Then
    Result := 4.0 * a * c - b * b  < 0
  else
    Result := a + b + c < 0;

End;

function Col_LineVsCircleXY;
  var
    p1      : TPolyLine2D;
    l1      : oeLine;
    i, t, k : Integer;
    x, y    : Single;
Begin

lLA := -1;
lLB := -1;

if not Col_LineVsCircle( L, Circ ) Then
  begin
    Result := FALSE;
    exit;
  end;
Result := TRUE;

t := 0;
p1.cX := Circ.cX;
p1.cY := Circ.cY;
p1.Count := Precision ;
k := M_Round( 360 / p1.Count );
SetLength( p1.Points, p1.Count + 1 );
for i := 0 to p1.Count - 1 do
  begin
    p1.Points[ i ].X := p1.cX + M_Cos( k * i ) * Circ.Radius;
    p1.Points[ i ].Y := p1.cY + M_Sin( k * i ) * Circ.Radius;
  end;
p1.Points[ p1.Count ].X := p1.Points[ 0 ].X;
p1.Points[ p1.Count ].Y := p1.Points[ 0 ].Y;


for i := 0 to p1.Count - 1 do
  begin
    l1.x0 := p1.Points[ i     ].X;
    l1.y0 := p1.Points[ i     ].Y;
    l1.x1 := p1.Points[ i + 1 ].X;
    l1.y1 := p1.Points[ i + 1 ].Y;
    if Col_Line( @l1, L ) Then
      begin
        INC( t );
        if t = 1 Then
          begin
            lLA := i;
            ColEx_CalcLineCross( @l1, L );
          end;
        if t = 2 Then
          begin
            lLB := i;
            x   := lX;
            y   := lY;
            ColEx_CalcLineCross( @l1, L );
            lX := ( x + lX ) / 2;
            lY := ( y + lY ) / 2;
            exit;
          end;
      end;
  end;

End;

function Col_LineVsPolyLine;
  var
    L : TLine2D;
    i : Integer;
Begin

lLA := -1;
lLB := -1;

for i := 0 to B^.Count - 1 do
  begin
    L.x0 := B^.Points[ i     ].X;
    L.y0 := B^.Points[ i     ].Y;
    L.x1 := B^.Points[ i + 1 ].X;
    L.y1 := B^.Points[ i + 1 ].Y;
    if Col_Line( @L, A ) Then
      begin
        Result := TRUE;
        lLA    := i;
        exit;
      end;
  end;
Result := FALSE;

{L.x0 := B^.Points[ 0 ].X;
L.y0 := B^.Points[ 0 ].Y;
if Col_Line( @L, A ) Then
  begin
    Result := TRUE;
    lLA    := i + 1;
  end else Result := FALSE;}

End;

// P O L Y L I N E ' s
function Col_PolyLine;
  var
    L1, L2 : TLine2D;
    i, j   : Integer;
Begin

lLA := -1;
lLB := -1;

for i := 0 to A^.Count - 1 do
  begin
    L1.x0 := A^.Points[ i     ].X;
    L1.y0 := A^.Points[ i     ].Y;
    L1.x1 := A^.Points[ i + 1 ].X;
    L1.y1 := A^.Points[ i + 1 ].Y;
    for j := 0 to B^.Count - 1 do
      begin
        L2.x0 := B^.Points[ j     ].X;
        L2.y0 := B^.Points[ j     ].Y;
        L2.x1 := B^.Points[ j + 1 ].X;
        L2.y1 := B^.Points[ j + 1 ].Y;
        if Col_Line( @L1, @L2 ) Then
          begin
            Result := TRUE;
            lLA    := i;
            lLB    := j;
            exit;
          end;
      end;
  end;
Result := FALSE;  

{L1.x0 := A^.Points[ 0 ].X;
L1.y0 := A^.Points[ 0 ].Y;
for i := 0 to High( B^.Points ) - 1 do
  begin
    L2.x0 := B^.Points[ i     ].X;
    L2.y0 := B^.Points[ i     ].Y;
    L2.x1 := B^.Points[ i + 1 ].X;
    L2.y1 := B^.Points[ i + 1 ].Y;
    if Col_Line( @L1, @L2 ) Then
      begin
        Result := TRUE;
        lLA    := High( A^.Points );
        lLA    := i;
        exit;
      end;
  end;
L2.x0 := B^.Points[ 0 ].X;
L2.y0 := B^.Points[ 0 ].Y;
for i := 0 to High( A^.Points ) - 1 do
  begin
    L1.x0 := A^.Points[ i     ].X;
    L1.y0 := A^.Points[ i     ].Y;
    L1.x1 := A^.Points[ i + 1 ].X;
    L1.y1 := A^.Points[ i + 1 ].Y;
    if Col_Line( @L1, @L2 ) Then
      begin
        Result := TRUE;
        lLA    := i;
        lLA    := High( A^.Points );
        exit;
      end;
  end;}

End;

function Col_PolyLineVsAABB;
  var
    L : TLine2D;
    i : Integer;
Begin

lLA := -1;
lLB := -1;

for i := 0 to A^.Count - 1 do
  begin
    L.x0 := A^.Points[ i     ].X;
    L.y0 := A^.Points[ i     ].Y;
    L.x1 := A^.Points[ i + 1 ].X;
    L.y1 := A^.Points[ i + 1 ].Y;
    if Col_LineVsAABB( @L, AABB ) Then
      begin
        Result := TRUE;
        lLA := i;
        exit;
      end;
  end;
Result := FALSE;

{L.x0 := A^.Points[ 0 ].X;
L.y0 := A^.Points[ 0 ].Y;
if Col_LineVsAABB( @L, AABB ) Then
  begin
    Result := TRUE;
    lLA    := i + 1;
  end else Result := FALSE;}

End;

function Col_PolyLineVsCircle;
  var
    L : TLine2D;
    i : Integer;
Begin
lLA := -1;
lLB := -1;

for i := 0 to A^.Count - 1 do
  begin
    L.x0 := A^.Points[ i     ].X;
    L.y0 := A^.Points[ i     ].Y;
    L.x1 := A^.Points[ i + 1 ].X;
    L.y1 := A^.Points[ i + 1 ].Y;
    if Col_LineVsCircle( @L, Circ ) Then
      begin
        Result := TRUE;
        lLA := i;
        exit;
      end;
  end;
Result := FALSE;

{L.x0 := A^.Points[ 0 ].X;
L.y0 := A^.Points[ 0 ].Y;
if Col_LineVsCircle( @L, Circ ) Then
  begin
    Result := TRUE;
    lLA    := i + 1;
  end else Result := FALSE;}
End;

function Col_PolyLineVsCircleXY;
  var
    L : TLine2D;
    i : Integer;
Begin
lLA := -1;
lLB := -1;

for i := 0 to A^.Count - 1 do
  begin
    L.x0 := A^.Points[ i     ].X;
    L.y0 := A^.Points[ i     ].Y;
    L.x1 := A^.Points[ i + 1 ].X;
    L.y1 := A^.Points[ i + 1 ].Y;
    if Col_LineVsCircleXY( @L, Circ, Precision ) Then
      begin
        Result := TRUE;
        lLA := i;
        exit;
      end;
  end;
Result := FALSE;

{L.x0 := A^.Points[ 0 ].X;
L.y0 := A^.Points[ 0 ].Y;
if Col_LineVsCircle( @L, Circ ) Then
  begin
    Result := TRUE;
    lLA    := i + 1;
  end else Result := FALSE;}

End;

// A A B B ' s
function Col_AABB;
Begin

if ( AABB1^.X + AABB1^.Width  >= AABB2^.X ) and ( AABB1^.X <= AABB2^.X + AABB2^.Width  ) and
   ( AABB1^.Y + AABB1^.Height >= AABB2^.Y ) and ( AABB1^.Y <= AABB2^.Y + AABB2^.Height ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_AABBInAABB;
Begin

if ( AABB1^.X > AABB2^.X ) and ( AABB1^.X + AABB1^.Width  < AABB2^.X + AABB2^.Width  ) and
   ( AABB1^.Y > AABB2^.Y ) and ( AABB1^.Y + AABB1^.Height < AABB2^.Y + AABB2^.Height ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_AABBInCircle;
Begin

if Col_PointInCircle( AABB^.X, AABB^.Y, Circ ) and
   Col_PointInCircle( AABB^.X + AABB^.Width, AABB^.Y + AABB^.Height, Circ ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_AABBVsCircle;
Begin

if ( Col_PointInCircle( AABB^.X,               AABB^.Y,                Circ ) or
     Col_PointInCircle( AABB^.X + AABB^.Width, AABB^.Y,                Circ ) or
     Col_PointInCircle( AABB^.X + AABB^.Width, AABB^.Y + AABB^.Height, Circ ) or
     Col_PointInCircle( AABB^.X,               AABB^.Y + AABB^.Height, Circ ) ) or
   ( Col_PointInAABB( Circ^.cX,                Circ^.cY - Circ^.Radius, AABB ) or
     Col_PointInAABB( Circ^.cX + Circ^.Radius, Circ^.cY - Circ^.Radius, AABB ) or
     Col_PointInAABB( Circ^.cX,                Circ^.cY + Circ^.Radius, AABB ) or
     Col_PointInAABB( Circ^.cX - Circ^.Radius, Circ^.cY,                AABB ) ) Then
  Result := TRUE
else
  Result := FALSE;

End;

// C I R C L E ' s
function Col_Circle;
Begin

if ( Circ1^.cX - Circ2^.cX ) * ( Circ1^.cX - Circ2^.cX ) +
   ( Circ1^.cY - Circ2^.cY ) * ( Circ1^.cY - Circ2^.cY ) <=
   ( Circ1^.Radius + Circ2^.Radius ) *
   ( Circ1^.Radius + Circ2^.Radius ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_CircleInCircle;
Begin

if ( Circ1^.cX - Circ2^.cX ) * ( Circ1^.cX - Circ2^.cX ) +
   ( Circ1^.cY - Circ2^.cY ) * ( Circ1^.cY - Circ2^.cY ) <
   ( Circ1^.Radius - Circ2^.Radius ) *
   ( Circ1^.Radius - Circ2^.Radius ) Then
  Result := TRUE
else
  Result := FALSE;

End;

function Col_CircleInAABB;
Begin

if Col_PointInAABB( Circ^.cX + Circ^.Radius, Circ^.cY + Circ^.Radius, AABB ) and
   Col_PointInAABB( Circ^.cX - Circ^.Radius, Circ^.cY + Circ^.Radius, AABB ) and
   Col_PointInAABB( Circ^.cX - Circ^.Radius, Circ^.cY - Circ^.Radius, AABB ) and
   Col_PointInAABB( Circ^.cX + Circ^.Radius, Circ^.cY - Circ^.Radius, AABB ) Then
  Result := TRUE
else
  Result := FALSE;

End;

//----------------------------------------------------------------------------//
//----------------------------- E X T E N D E D ------------------------------//
//----------------------------------------------------------------------------//

// G E T ' s
function ColEx_LastX;
Begin
Result := lX;
End;

function ColEx_LastY;
Begin
Result := lY;
End;

function ColEx_LastLineA;
Begin
Result := lLA;
End;

function ColEx_LastLineB;
Begin
Result := lLB;
End;

// T R A N S F O R M A T I N ' s
procedure ColEx_PolyRotate;
  var
    i, ang : Integer;
Begin
// Только не смеятся)) Почему при повороте PolyLine начинает убавлять в размерах, я без понятия, поэтому пришлось решать проблему методом через ж^W
ang := M_Round( Angle );
for i := 0 to A^.Count do
  begin
    B^.Points[ i ].X := A^.cX + ( A^.Points[ i ].X - A^.cX ) * M_Cos( ang ) * 1.000153 - ( A^.Points[ i ].Y - A^.cY ) * M_Sin( ang ) * 1.000153;
    B^.Points[ i ].Y := A^.cY + ( A^.Points[ i ].X - A^.cX ) * M_Sin( ang ) * 1.000153 + ( A^.Points[ i ].Y - A^.cY ) * M_Cos( ang ) * 1.000153;
  end;
End;

procedure ColEx_PolyScale;
  var
    i : Integer;
Begin

for i := 0 to A^.Count do
  begin
    A^.Points[ i ].X := A^.cX + ( A^.Points[ i ].X - A^.cX ) * ScaleX;
    A^.Points[ i ].Y := A^.cY + ( A^.Points[ i ].Y - A^.cY ) * ScaleY;
  end;

End;

procedure ColEx_PolyMove;
  var
    i : Integer;
Begin

B^.cX := A^.cX + X;
B^.cY := A^.cY + Y;
for i := 0 to A^.Count do
  begin
    B^.Points[ i ].X := A^.Points[ i ].X + X;
    B^.Points[ i ].Y := A^.Points[ i ].Y + Y;
  end;

End;

procedure ColEx_PolyCenter;
  var
    i      : Integer;
    Ex, Ey : Single;
Begin

Ex := 0; Ey := 0;
for i := 0 to A^.Count - 1 do
  Ex := Ex + A^.Points[ i ].X;
for i := 0 to A^.Count - 1 do
  Ey := Ey + A^.Points[ i ].Y;

A^.cX := Ex / A^.Count;
A^.cY := Ey / A^.Count;

End;

procedure ColEx_PolyRect;
  var
    i          : Integer;
    minX, maxX : Single;
    minY, maxY : Single;
Begin

minX := A^.Points[ 0 ].X;
minY := A^.Points[ 0 ].Y;
maxX := 0;
maxY := 0;
for i := 0 to A^.Count - 1 do
  begin
    if A^.Points[ i ].X < minX Then minX := A^.Points[ i ].X;
    if A^.Points[ i ].Y < minY Then minY := A^.Points[ i ].Y;
    if A^.Points[ i ].X > maxX Then maxX := A^.Points[ i ].X;
    if A^.Points[ i ].Y > maxY Then maxY := A^.Points[ i ].Y;
  end;

Rect^.X      := minX;
Rect^.Y      := minY;
Rect^.Width  := maxX - minX;
Rect^.Height := maxY - minY;

End;

// L I N E ' s
procedure ColEx_CalcLineCross;
  var
    S1 : array[ 0..1 ] of Single;
Begin

S1[ 0 ] := A^.x1 - A^.x0;
S1[ 1 ] := A^.y1 - A^.y0;

lX := A^.x0 + lT * S1[ 0 ];
lY := A^.y0 + lT * S1[ 1 ];

//x := A.x0 + t * s1[0];
//y := A.y0 + t * s1[1];

//x := p2[0] + s * s2[0];
//y := p2[1] + s * s2[1];

End;

end.                    
