Path: blob/master/SLICK_HOME/src/org/newdawn/slick/geom/Line.java
1461 views
package org.newdawn.slick.geom;12/**3* Implemenation of a bunch of maths functions to do with lines. Note4* that lines can't be used as dynamic shapes right now - also collision5* with the end of a line is undefined.6*7* @author Kevin Glass8*/9public class Line extends Shape {10/** The start point of the line */11private Vector2f start;12/** The end point of the line */13private Vector2f end;14/** The vector between the two points */15private Vector2f vec;16/** The length of the line squared */17private float lenSquared;1819/** Temporary storage - declared globally to reduce GC */20private Vector2f loc = new Vector2f(0,0);21/** Temporary storage - declared globally to reduce GC */22private Vector2f v = new Vector2f(0,0);23/** Temporary storage - declared globally to reduce GC */24private Vector2f v2 = new Vector2f(0,0);25/** Temporary storage - declared globally to reduce GC */26private Vector2f proj = new Vector2f(0,0);2728/** Temporary storage - declared globally to reduce GC */29private Vector2f closest = new Vector2f(0,0);30/** Temporary storage - declared globally to reduce GC */31private Vector2f other = new Vector2f(0,0);3233/** True if this line blocks on the outer edge */34private boolean outerEdge = true;35/** True if this line blocks on the inner edge */36private boolean innerEdge = true;3738/**39* Create a new line based on the origin and a single point40*41* @param x The end point of the line42* @param y The end point of the line43* @param inner True if this line blocks on it's inner edge44* @param outer True if this line blocks on it's outer edge45*/46public Line(float x, float y, boolean inner, boolean outer) {47this(0,0,x,y);48}4950/**51* Create a new line based on the origin and a single point52*53* @param x The end point of the line54* @param y The end point of the line55*/56public Line(float x, float y) {57this(x,y,true,true);58}5960/**61* Create a new line based on two points62*63* @param x1 The x coordinate of the start point64* @param y1 The y coordinate of the start point65* @param x2 The x coordinate of the end point66* @param y2 The y coordinate of the end point67*/68public Line(float x1, float y1, float x2, float y2) {69this(new Vector2f(x1,y1), new Vector2f(x2,y2));70}7172/**73* Create a line with relative second point74*75* @param x1 The x coordinate of the start point76* @param y1 The y coordinate of the start point77* @param dx The x change to get to the second point78* @param dy The y change to get to the second point79* @param dummy A dummy value80*/81public Line(float x1, float y1, float dx, float dy, boolean dummy) {82this(new Vector2f(x1,y1), new Vector2f(x1+dx,y1+dy));83}8485/**86* Create a new line based on two points87*88* @param start The start point89* @param end The end point90*/91public Line(Vector2f start, Vector2f end) {92super();9394set(start,end);95}9697/**98* Get the start point of the line99*100* @return The start point of the line101*/102public Vector2f getStart() {103return start;104}105106/**107* Get the end point of the line108*109* @return The end point of the line110*/111public Vector2f getEnd() {112return end;113}114115/**116* Find the length of the line117*118* @return The the length of the line119*/120public float length() {121return vec.length();122}123124/**125* Find the length of the line squared (cheaper and good for comparisons)126*127* @return The length of the line squared128*/129public float lengthSquared() {130return vec.lengthSquared();131}132133/**134* Configure the line135*136* @param start The start point of the line137* @param end The end point of the line138*/139public void set(Vector2f start, Vector2f end) {140super.pointsDirty = true;141if (this.start == null) {142this.start = new Vector2f();143}144this.start.set(start);145146if (this.end == null) {147this.end = new Vector2f();148}149this.end.set(end);;150151vec = new Vector2f(end);152vec.sub(start);153154lenSquared = vec.lengthSquared();155}156157/**158* Configure the line without garbage159*160* @param sx The x coordinate of the start161* @param sy The y coordinate of the start162* @param ex The x coordiante of the end163* @param ey The y coordinate of the end164*/165public void set(float sx, float sy, float ex, float ey) {166super.pointsDirty = true;167start.set(sx, sy);168end.set(ex,ey);169170float dx = (ex-sx);171float dy = (ey-sy);172173lenSquared = (dx*dx)+(dy*dy);174}175176/**177* Get the x direction of this line178*179* @return The x direction of this line180*/181public float getDX() {182return end.getX() - start.getX();183}184185/**186* Get the y direction of this line187*188* @return The y direction of this line189*/190public float getDY() {191return end.getY() - start.getY();192}193194/**195* @see org.newdawn.slick.geom.Shape#getX()196*/197public float getX() {198return getX1();199}200201/**202* @see org.newdawn.slick.geom.Shape#getY()203*/204public float getY() {205return getY1();206}207208/**209* Get the x coordinate of the start point210*211* @return The x coordinate of the start point212*/213public float getX1() {214return start.getX();215}216217/**218* Get the y coordinate of the start point219*220* @return The y coordinate of the start point221*/222public float getY1() {223return start.getY();224}225226/**227* Get the x coordinate of the end point228*229* @return The x coordinate of the end point230*/231public float getX2() {232return end.getX();233}234235/**236* Get the y coordinate of the end point237*238* @return The y coordinate of the end point239*/240public float getY2() {241return end.getY();242}243244/**245* Get the shortest distance from a point to this line246*247* @param point The point from which we want the distance248* @return The distance from the line to the point249*/250public float distance(Vector2f point) {251return (float) Math.sqrt(distanceSquared(point));252}253254/**255* Check if the given point is on the line256*257* @param point The point to check258* @return True if the point is on this line259*/260public boolean on(Vector2f point) {261getClosestPoint(point, closest);262263return point.equals(closest);264}265266/**267* Get the shortest distance squared from a point to this line268*269* @param point The point from which we want the distance270* @return The distance squared from the line to the point271*/272public float distanceSquared(Vector2f point) {273getClosestPoint(point, closest);274closest.sub(point);275276float result = closest.lengthSquared();277278return result;279}280281/**282* Get the closest point on the line to a given point283*284* @param point The point which we want to project285* @param result The point on the line closest to the given point286*/287public void getClosestPoint(Vector2f point, Vector2f result) {288loc.set(point);289loc.sub(start);290291float projDistance = vec.dot(loc);292293projDistance /= vec.lengthSquared();294295if (projDistance < 0) {296result.set(start);297return;298}299if (projDistance > 1) {300result.set(end);301return;302}303304result.x = start.getX() + projDistance * vec.getX();305result.y = start.getY() + projDistance * vec.getY();306}307308/**309* @see java.lang.Object#toString()310*/311public String toString() {312return "[Line "+start+","+end+"]";313}314315/**316* Intersect this line with another317*318* @param other The other line we should intersect with319* @return The intersection point or null if the lines are parallel320*/321public Vector2f intersect(Line other) {322return intersect(other, false);323}324325/**326* Intersect this line with another327*328* @param other The other line we should intersect with329* @param limit True if the collision is limited to the extent of the lines330* @return The intersection point or null if the lines don't intersect331*/332public Vector2f intersect(Line other, boolean limit) {333Vector2f temp = new Vector2f();334335if (!intersect(other, limit, temp)) {336return null;337}338339return temp;340}341342/**343* Intersect this line with another344*345* @param other The other line we should intersect with346* @param limit True if the collision is limited to the extent of the lines347* @param result The resulting intersection point if any348* @return True if the lines intersect349*/350public boolean intersect(Line other, boolean limit, Vector2f result) {351float dx1 = end.getX() - start.getX();352float dx2 = other.end.getX() - other.start.getX();353float dy1 = end.getY() - start.getY();354float dy2 = other.end.getY() - other.start.getY();355float denom = (dy2 * dx1) - (dx2 * dy1);356357if (denom == 0) {358return false;359}360361float ua = (dx2 * (start.getY() - other.start.getY())) - (dy2 * (start.getX() - other.start.getX()));362ua /= denom;363float ub = (dx1 * (start.getY() - other.start.getY())) - (dy1 * (start.getX() - other.start.getX()));364ub /= denom;365366if ((limit) && ((ua < 0) || (ua > 1) || (ub < 0) || (ub > 1))) {367return false;368}369370float u = ua;371372float ix = start.getX() + (u * (end.getX() - start.getX()));373float iy = start.getY() + (u * (end.getY() - start.getY()));374375result.set(ix,iy);376return true;377}378379/**380* @see org.newdawn.slick.geom.Shape#createPoints()381*/382protected void createPoints() {383points = new float[4];384points[0] = getX1();385points[1] = getY1();386points[2] = getX2();387points[3] = getY2();388}389390/**391* @see org.newdawn.slick.geom.Shape#transform(org.newdawn.slick.geom.Transform)392*/393public Shape transform(Transform transform) {394float[] temp = new float[4];395createPoints();396transform.transform(points, 0, temp, 0, 2);397398return new Line(temp[0],temp[1],temp[2],temp[3]);399}400401/**402* @see org.newdawn.slick.geom.Shape#closed()403*/404public boolean closed() {405return false;406}407}408409410