com.github.mathiewz.slick.geom.Line Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of modernized-slick Show documentation
Show all versions of modernized-slick Show documentation
The main purpose of this libraryis to modernize and maintain the slick2D library.
The newest version!
package com.github.mathiewz.slick.geom;
/**
* Implemenation of a bunch of maths functions to do with lines. Note that lines
* can't be used as dynamic shapes right now - also collision with the end of a
* line is undefined.
*
* @author Kevin Glass
*/
public class Line extends Shape {
/** The start point of the line */
private Vector2f start;
/** The end point of the line */
private Vector2f end;
/** The vector between the two points */
private Vector2f vec;
/** Temporary storage - declared globally to reduce GC */
private final Vector2f loc = new Vector2f(0, 0);
/** Temporary storage - declared globally to reduce GC */
private final Vector2f closest = new Vector2f(0, 0);
/**
* Create a new line based on the origin and a single point
*
* @param x
* The end point of the line
* @param y
* The end point of the line
*/
public Line(float x, float y) {
this(0, 0, x, y);
}
/**
* Create a new line based on two points
*
* @param x1
* The x coordinate of the start point
* @param y1
* The y coordinate of the start point
* @param x2
* The x coordinate of the end point
* @param y2
* The y coordinate of the end point
*/
public Line(float x1, float y1, float x2, float y2) {
this(new Vector2f(x1, y1), new Vector2f(x2, y2));
}
/**
* Create a line with relative second point
*
* @param x1
* The x coordinate of the start point
* @param y1
* The y coordinate of the start point
* @param dx
* The x change to get to the second point
* @param dy
* The y change to get to the second point
*/
public Line(float x1, float y1, float dx, float dy, boolean isDeltaMode) {
this(new Vector2f(x1, y1), new Vector2f(x1 + dx, y1 + dy));
}
/**
* Create a new line based on two points
*
* @param start
* The start point
* @param end
* The end point
*/
public Line(float[] start, float[] end) {
super();
set(start, end);
}
/**
* Create a new line based on two points
*
* @param start
* The start point
* @param end
* The end point
*/
public Line(Vector2f start, Vector2f end) {
super();
set(start, end);
}
/**
* Configure the line
*
* @param start
* The start point of the line
* @param end
* The end point of the line
*/
public void set(float[] start, float[] end) {
set(start[0], start[1], end[0], end[1]);
}
/**
* Get the start point of the line
*
* @return The start point of the line
*/
public Vector2f getStart() {
return start;
}
/**
* Get the end point of the line
*
* @return The end point of the line
*/
public Vector2f getEnd() {
return end;
}
/**
* Find the length of the line
*
* @return The the length of the line
*/
public float length() {
return vec.length();
}
/**
* Find the length of the line squared (cheaper and good for comparisons)
*
* @return The length of the line squared
*/
public float lengthSquared() {
return vec.lengthSquared();
}
/**
* Configure the line
*
* @param start
* The start point of the line
* @param end
* The end point of the line
*/
public void set(Vector2f start, Vector2f end) {
super.pointsDirty = true;
if (this.start == null) {
this.start = new Vector2f();
}
this.start.set(start);
if (this.end == null) {
this.end = new Vector2f();
}
this.end.set(end);
vec = new Vector2f(end);
vec.sub(start);
vec.lengthSquared();
}
/**
* Configure the line without garbage
*
* @param sx
* The x coordinate of the start
* @param sy
* The y coordinate of the start
* @param ex
* The x coordiante of the end
* @param ey
* The y coordinate of the end
*/
public void set(float sx, float sy, float ex, float ey) {
super.pointsDirty = true;
start.set(sx, sy);
end.set(ex, ey);
float dx = ex - sx;
float dy = ey - sy;
vec.set(dx, dy);
}
/**
* Get the x direction of this line
*
* @return The x direction of this line
*/
public float getDX() {
return end.getX() - start.getX();
}
/**
* Get the y direction of this line
*
* @return The y direction of this line
*/
public float getDY() {
return end.getY() - start.getY();
}
/**
* @see com.github.mathiewz.slick.geom.Shape#getX()
*/
@Override
public float getX() {
return getX1();
}
/**
* @see com.github.mathiewz.slick.geom.Shape#getY()
*/
@Override
public float getY() {
return getY1();
}
/**
* Get the x coordinate of the start point
*
* @return The x coordinate of the start point
*/
public float getX1() {
return start.getX();
}
/**
* Get the y coordinate of the start point
*
* @return The y coordinate of the start point
*/
public float getY1() {
return start.getY();
}
/**
* Get the x coordinate of the end point
*
* @return The x coordinate of the end point
*/
public float getX2() {
return end.getX();
}
/**
* Get the y coordinate of the end point
*
* @return The y coordinate of the end point
*/
public float getY2() {
return end.getY();
}
/**
* Get the shortest distance from a point to this line
*
* @param point
* The point from which we want the distance
* @return The distance from the line to the point
*/
public float distance(Vector2f point) {
return (float) Math.sqrt(distanceSquared(point));
}
/**
* Check if the given point is on the line
*
* @param point
* The point to check
* @return True if the point is on this line
*/
public boolean on(Vector2f point) {
getClosestPoint(point, closest);
return point.equals(closest);
}
/**
* Get the shortest distance squared from a point to this line
*
* @param point
* The point from which we want the distance
* @return The distance squared from the line to the point
*/
public float distanceSquared(Vector2f point) {
getClosestPoint(point, closest);
closest.sub(point);
return closest.lengthSquared();
}
/**
* Get the closest point on the line to a given point
*
* @param point
* The point which we want to project
* @param result
* The point on the line closest to the given point
*/
public void getClosestPoint(Vector2f point, Vector2f result) {
loc.set(point);
loc.sub(start);
float projDistance = vec.dot(loc);
projDistance /= vec.lengthSquared();
if (projDistance < 0) {
result.set(start);
return;
}
if (projDistance > 1) {
result.set(end);
return;
}
result.setX(start.getX() + projDistance * vec.getX());
result.setY(start.getY() + projDistance * vec.getY());
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "[Line " + start + "," + end + "]";
}
/**
* Intersect this line with another
*
* @param other
* The other line we should intersect with
* @return The intersection point or null if the lines are parallel
*/
public Vector2f intersect(Line other) {
return intersect(other, false);
}
/**
* Intersect this line with another
*
* @param other
* The other line we should intersect with
* @param limit
* True if the collision is limited to the extent of the lines
* @return The intersection point or null if the lines don't intersect
*/
public Vector2f intersect(Line other, boolean limit) {
Vector2f temp = new Vector2f();
if (!intersect(other, limit, temp)) {
return null;
}
return temp;
}
/**
* Intersect this line with another
*
* @param other
* The other line we should intersect with
* @param limit
* True if the collision is limited to the extent of the lines
* @param result
* The resulting intersection point if any
* @return True if the lines intersect
*/
public boolean intersect(Line other, boolean limit, Vector2f result) {
float dx1 = end.getX() - start.getX();
float dx2 = other.end.getX() - other.start.getX();
float dy1 = end.getY() - start.getY();
float dy2 = other.end.getY() - other.start.getY();
float denom = dy2 * dx1 - dx2 * dy1;
if (denom == 0) {
return false;
}
float ua = dx2 * (start.getY() - other.start.getY()) - dy2 * (start.getX() - other.start.getX());
ua /= denom;
float ub = dx1 * (start.getY() - other.start.getY()) - dy1 * (start.getX() - other.start.getX());
ub /= denom;
if (limit && (ua < 0 || ua > 1 || ub < 0 || ub > 1)) {
return false;
}
float u = ua;
float ix = start.getX() + u * (end.getX() - start.getX());
float iy = start.getY() + u * (end.getY() - start.getY());
result.set(ix, iy);
return true;
}
/**
* @see com.github.mathiewz.slick.geom.Shape#createPoints()
*/
@Override
protected void createPoints() {
points = new Float[4];
points[0] = getX1();
points[1] = getY1();
points[2] = getX2();
points[3] = getY2();
}
/**
* @see com.github.mathiewz.slick.geom.Shape#transform(com.github.mathiewz.slick.geom.Transform)
*/
@Override
public Shape transform(Transform transform) {
Float[] temp = new Float[4];
createPoints();
transform.transform(points, 0, temp, 0, 2);
return new Line(temp[0], temp[1], temp[2], temp[3]);
}
/**
* @see com.github.mathiewz.slick.geom.Shape#closed()
*/
@Override
public boolean closed() {
return false;
}
/**
* @see com.github.mathiewz.slick.geom.Shape#intersects(com.github.mathiewz.slick.geom.Shape)
*/
@Override
public boolean intersects(Shape shape) {
if (shape instanceof Circle) {
return shape.intersects(this);
}
return super.intersects(shape);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy