package com.gebauz.bauzoid2.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 boolean isCollinearPointOnSegment
(float x,
float y
)
{
//Gdx.app.log("BLA", "p: " + x + ", " + y + " [" + ax + ", " + ay + " - " + bx + ", " + by);
final 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 final float getA
()
{
return b.
y - a.
y;
}
/** Get the B coefficient in the Ax + By = C form. */
public final float getB
()
{
return a.
x - b.
x;
}
/** Get the C coefficient in the Ax + By = C form. */
public final 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 boolean 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 boolean 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 boolean 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
);
}
/*
(P-A).D == |X-A|
X == A + ((P-A).D)D
Desired perpendicular: X-P
Returns the closest point x on segment ab to point p
(x-p).(b-a) = 0, x = a + t(b-a)
=> (a + t(b-a) - p).(b-a) = 0
=> t(b-a).(b-a) = (p-a).(b-a)
=> t = (p-a).(b-a) / |b-a|^2
Ogre::Vector3 closestPointOnLineSegment(const Ogre::Vector3 &p,const Ogre::Vector3 &a,const Ogre::Vector3 b)
{
Ogre::Vector3 ab = b-a;
float t = (p-a).dotProduct(ab) / (ab).squaredLength();
t = Ogre::Math::Clamp(t,0.f,1.f);
return a + t*ab;
}
*
*
*
*/
// Getters/Setters==================================================================================
}