package com.gebauz.bauzoid.math;
/** Line segment class. */
public class Line2
{
// Constants========================================================================================
// Embedded Types===================================================================================
// Fields===========================================================================================
private float ax =
0;
private float ay =
0;
private float bx =
0;
private float by =
0;
// parametric form
private float A = 0.0f
;
private float B = 0.0f
;
private float C = 0.0f
;
// Methods==========================================================================================
public Line2
()
{
calcParametric
();
}
public Line2
(float _ax,
float _ay,
float _bx,
float _by
)
{
ax = _ax
; ay = _ay
;
bx = _bx
; by = _by
;
calcParametric
();
}
public Line2
(Vector2 a, Vector2 b
)
{
ax = a.
x; ay = a.
y;
bx = b.
x; by = b.
y;
calcParametric
();
}
public Vector2 getLineVector
()
{
return new Vector2
(bx - ax, by - ay
);
}
public void calcParametric
()
{
A = getA
();
B = getB
();
C = getC
();
}
public float getLengthSqr
()
{
float diffX = ax - bx
;
float diffY = ay - by
;
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
)
{
if ((x
<=
Math.
max(ax, bx
)) && (x
>=
Math.
min(ax, bx
)) &&
(y
<=
Math.
max(ay, by
)) && (y
>=
Math.
min(ay, by
)))
{
return true;
}
return false;
}
/** Get the A coefficient in the Ax + By = C form. */
public final float getA
()
{
return by - ay
;
}
/** Get the B coefficient in the Ax + By = C form. */
public final float getB
()
{
return ax - bx
;
}
/** Get the C coefficient in the Ax + By = C form. */
public final float getC
()
{
return getA
() * ax + getB
() * ay
;
}
public Vector2 getLineIntersection
(Line2 other
)
{
// 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 null;
float x =
(B2
*C1 - B1
*C2
)/delta
;
float y =
(A1
*C2 - A2
*C1
)/delta
;
return new Vector2
(x, y
);
}
public Vector2 getSegmentIntersection
(Line2 other
)
{
Vector2 p = getLineIntersection
(other
);
if (p ==
null)
return null;
if (this.
isCollinearPointOnSegment(p.
x, p.
y) && other.
isCollinearPointOnSegment(p.
x, p.
y))
return p
;
return null;
}
public boolean intersectsSegment
(Line2 other
)
{
Vector2 p = getSegmentIntersection
(other
);
if (p ==
null)
return false;
return true;
}
/** 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);
}
/** 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
)
{
Vector2 ab = getLineVector
();
Vector2 ap =
new Vector2
(point.
x - ax, point.
y - ay
);
float t = Vector2.
dotProduct(ap, ab
) / ab.
squaredLength();
t = MathUtil.
clamp(t,
0,
1);
return new Vector2
(ax + t
* ab.
x, ay + t
* ab.
y);
}
public Vector2 getClosestPointFrom
(float px,
float py
)
{
return getClosestPointFrom
(new Vector2
(px, py
));
}
/*
(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==================================================================================
}