using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BauzoidNET
.math
{
/** Line segment class. */
public class Line2
{
// Constants========================================================================================
// Embedded Types===================================================================================
// Fields===========================================================================================
public Vector2 a
= new Vector2
();
public Vector2 b
= new Vector2
();
// parametric form
private float A
= 0
.0f
;
private float B
= 0
.0f
;
private float C
= 0
.0f
;
private Vector2 mTemp
= new Vector2
();
private Vector2 mTemp2
= new Vector2
();
// Methods==========================================================================================
public Line2
()
{
calcParametric
();
}
public Line2
(float ax,
float ay,
float bx,
float by
)
{
set
(ax, ay, bx, by
);
}
public Line2
(Vector2 a, Vector2 b
)
{
set
(a, b
);
}
public void set
(float _ax,
float _ay,
float _bx,
float _by
)
{
a
.x = _ax
; a
.y = _ay
;
b
.x = _bx
; b
.y = _by
;
calcParametric
();
}
public void set
(Vector2 _a, Vector2 _b
)
{
a
.x = _a
.x; a
.y = _a
.y;
b
.x = _b
.x; b
.y = _b
.y;
calcParametric
();
}
public void setPointA
(float _ax,
float _ay
)
{
a
.x = _ax
; a
.y = _ay
;
calcParametric
();
}
public void setPointB
(float _bx,
float _by
)
{
b
.x = _bx
; b
.y = _by
;
calcParametric
();
}
public Line2 copy
()
{
return new Line2
(a, b
);
}
public Vector2 getMidPoint
()
{
return new Vector2
(a
.x + (b
.x - a
.x) / 2, a
.y + (b
.y - a
.y) /2);
}
public Vector2 getLineVector
()
{
return new Vector2
(b
.x - a
.x, b
.y - a
.y);
}
public void getLineVector
(Vector2 result
)
{
result
.set(b
.x - a
.x, b
.y - a
.y);
}
public void calcParametric
()
{
A
= getA
();
B
= getB
();
C
= getC
();
}
public float getLengthSqr
()
{
float diffX
= a
.x - b
.x;
float diffY
= a
.y - b
.y;
return (diffX
*diffX
+ diffY
*diffY
);
}
public float getLength
()
{
float length
= getLengthSqr
();
return (float)(Math
.Sqrt(length
));
}
/** Check if x, y (which must be collinear to the line segment) lies within the line segment. */
public bool isCollinearPointOnSegment
(float x,
float y
)
{
//Gdx.app.log("BLA", "p: " + x + ", " + y + " [" + ax + ", " + ay + " - " + bx + ", " + by);
float EPSILON
= 0
.0001f
;
if ((x
<= (Math
.Max(a
.x, b
.x) + EPSILON
)) && (x
>= (Math
.Min(a
.x, b
.x) - EPSILON
)) &&
(y
<= (Math
.Max(a
.y, b
.y) + EPSILON
)) && (y
>= (Math
.Min(a
.y, b
.y) - EPSILON
)))
{
return true;
}
return false;
}
/** Get the A coefficient in the Ax + By = C form. */
public float getA
()
{
return b
.y - a
.y;
}
/** Get the B coefficient in the Ax + By = C form. */
public float getB
()
{
return a
.x - b
.x;
}
/** Get the C coefficient in the Ax + By = C form. */
public float getC
()
{
return getA
() * a
.x + getB
() * a
.y;
}
/** Get intersection point. */
public Vector2 getLineIntersection
(Line2 other
)
{
Vector2 result
= new Vector2
();
if (getLineIntersection
(other, result
))
return result
;
return null;
}
/** Get intersection point (no allocation version). */
public bool getLineIntersection
(Line2 other, Vector2 result
)
{
// get Ax + By = C form coefficients
float A1
= A
;
float B1
= B
;
float C1
= C
;
float A2
= other
.A;
float B2
= other
.B;
float C2
= other
.C;
float delta
= A1
*B2
- A2
*B1
;
if (delta
== 0)
return false;
float x
= (B2
*C1
- B1
*C2
)/delta
;
float y
= (A1
*C2
- A2
*C1
)/delta
;
result
.set(x, y
);
return true;
}
/** Get line segment intersection point. */
public Vector2 getSegmentIntersection
(Line2 other
)
{
Vector2 result
= new Vector2
();
if (getSegmentIntersection
(other, result
))
return result
;
return null;
}
/** Get line segment intersection point (no allocation version). */
public bool getSegmentIntersection
(Line2 other, Vector2 result
)
{
if (!getLineIntersection
(other, result
))
return false;
if (this.isCollinearPointOnSegment(result
.x, result
.y) && other
.isCollinearPointOnSegment(result
.x, result
.y))
return true;
return false;
}
/** Check if a segment intersects another. */
public bool intersectsSegment
(Line2 other
)
{
return getSegmentIntersection
(other, mTemp
);
}
/** Get the smallest perpendicular vector from point to the line. */
public Vector2 getMinimalVectorFrom
(Vector2 point
)
{
/*Vector2 closestPoint = getClosestPointFrom(point);
return new Vector2(closestPoint.x - point.x, closestPoint.y - point.y);*/
Vector2 result
= new Vector2
();
getMinimalVectorFrom
(point, result
);
return result
;
}
/** Get the smallest perpendicular vector from point to the line (no allocation version). */
public void getMinimalVectorFrom
(Vector2 point, Vector2 result
)
{
//Vector2 closestPoint = getClosestPointFrom(point);
getClosestPointFrom
(point, mTemp
);
result
.set(mTemp
.x - point
.x, mTemp
.y - point
.y);
//return new Vector2(closestPoint.x - point.x, closestPoint.y - point.y);
}
/** Get the smallest perpendicular vector from point to the line. */
public Vector2 getMinimalVectorFrom
(float px,
float py
)
{
return getMinimalVectorFrom
(new Vector2
(px, py
));
}
/** Get the closest point on line from a given point. */
public Vector2 getClosestPointFrom
(Vector2 point
)
{
return getClosestPointFrom
(point
.x, point
.y);
}
/** Get the closest point on line from a given point (no allocation version). */
public void getClosestPointFrom
(Vector2 point, Vector2 result
)
{
getClosestPointFrom
(point
.x, point
.y, result
);
}
/** Get the closest point on line from a given point. */
public Vector2 getClosestPointFrom
(float px,
float py
)
{
Vector2 result
= new Vector2
();
getClosestPointFrom
(px, py, result
);
return result
;
}
/** Get the closest point on line from a given point (no allocation version). */
public void getClosestPointFrom
(float px,
float py, Vector2 result
)
{
getLineVector
(mTemp
);
mTemp2
.set(px
- a
.x, py
- a
.y);
float t
= Vector2
.dotProduct(mTemp, mTemp2
) / mTemp
.squaredLength();
t
= MathUtil
.clamp(t,
0,
1);
result
.set(a
.x + t
* mTemp
.x, a
.y + t
* mTemp
.y);
}
/** Get the closest distance from a given point. */
public float getClosestDistanceFrom
(Vector2 point
)
{
return getClosestDistanceFrom
(point
.x, point
.y);
}
/** Get the closest distance from a given point. */
public float getClosestDistanceFrom
(float px,
float py
)
{
return (float)Math
.Sqrt(getClosestSquaredDistanceFrom
(px, py
));
}
/** Get the closest distance from a given point. */
public float getClosestSquaredDistanceFrom
(float px,
float py
)
{
getClosestPointFrom
(px, py, mTemp
);
float dx
= mTemp
.x - px
;
float dy
= mTemp
.y - py
;
return (dx
*dx
+ dy
*dy
);
}
}
}