Package framework.spacial

Source Code of framework.spacial.Line

package framework.spacial;

import java.io.IOException;

import main.L;

import org.newdawn.slick.geom.Vector2f;

import framework.io.CustomInputStream;
import framework.io.CustomOutputStream;
import framework.io.Writeable;

public class Line implements Writeable {

  private Vector2f from;
  private Vector2f to;

  public Line(Vector2f from, Vector2f to){
    this.from = from;
    this.to = to;
  }

  public Line(CustomInputStream in) throws IOException{
    this.from = in.readVector();
    this.to = in.readVector();
  }

  public Line(Vector2f from, float toX, float toY){
    this(from, new Vector2f(toX, toY));
  }

  public Line(float fromX, float fromY, Vector2f to){
    this(new Vector2f(fromX, fromY), to);
  }

  public Line(float fromX,float fromY, float toX,float toY){
    this(new Vector2f(fromX, fromY), new Vector2f(toX, toY));
  }

  public Vector2f getIntersectionWith(Line otherLine){
    return getLineLineIntersection(getFrom().getX(), getFrom().getY(), getTo().getX(), getTo().getY(), otherLine.getFrom().getX(), otherLine.getFrom().getY(), otherLine.getTo().getX(), otherLine.getTo().getY());
  }

  public boolean intersetsWith(Line otherLine){
    return linesIntersect(getFrom().getX(), getFrom().getY(), getTo().getX(), getTo().getY(), otherLine.getFrom().getX(), otherLine.getFrom().getY(), otherLine.getTo().getX(), otherLine.getTo().getY());
  }

  public Vector2f getClosestPointTo(Vector2f p){
    return getClosestPoint(from, to, p);
  }

  public boolean isOnLine(float tollerance, Vector2f point){
    return point != null && getClosestPointTo(point).sub(point).length() <= tollerance;
  }
 
  public boolean isOnLine(Vector2f point){
    return isOnLine(0.001f, point);
  }

  public float getShortestDistanceTo(Vector2f p){
    return getClosestPointTo(p).sub(p).length();
  }
 
  @Override
  public void writeToStream(CustomOutputStream out) throws IOException {
    out.write(from);
    out.write(to);
  }

  public Vector2f getFrom() {
    return from.copy();
  }

  public void setFrom(Vector2f from) {
    this.from = from;
  }

  public Vector2f getTo() {
    return to.copy();
  }

  public void setTo(Vector2f to) {
    this.to = to;
  }

  public Line copy(){
    return new Line(from.copy(), to.copy());
  }

  public Line translate(Vector2f v){
    from.add(v);
    to.add(v);
    return this;
  }

  public void rotate(float theta){
    from.setTheta(from.getTheta() + theta);
    to.setTheta(from.getTheta() + theta);
  }

  public void rotateAround(float theta, Vector2f centre){
    VectorUtil.rotateAround(from,centre, theta);
    VectorUtil.rotateAround(to,centre, theta);
  }
 
  public float getXWidth(){
    if(from != null && to != null){
      return Math.abs(from.getX() - to.getX());
    }
    return 0;
  }
 
  public float getYHeight(){
    if(from != null && to != null){
      return Math.abs(from.getY() - to.getY());
    }
    return 0;
  }
 
  public float getLength(){
    return getTo().sub(getFrom()).length();
  }
 
  //NOT MY CODE:
 
 
  public static boolean linesIntersect(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4){
    // Return false if either of the lines have zero length
    if (x1 == x2 && y1 == y2 ||
        x3 == x4 && y3 == y4){
      return false;
    }
    // Fastest method, based on Franklin Antonio's "Faster Line Segment Intersection" topic "in Graphics Gems III" book (http://www.graphicsgems.org/)
    float ax = x2-x1;
    float ay = y2-y1;
    float bx = x3-x4;
    float by = y3-y4;
    float cx = x1-x3;
    float cy = y1-y3;

    float alphaNumerator = by*cx - bx*cy;
    float commonDenominator = ay*bx - ax*by;
    if (commonDenominator > 0){
      if (alphaNumerator < 0 || alphaNumerator > commonDenominator){
        return false;
      }
    }else if (commonDenominator < 0){
      if (alphaNumerator > 0 || alphaNumerator < commonDenominator){
        return false;
      }
    }
    float betaNumerator = ax*cy - ay*cx;
    if (commonDenominator > 0){
      if (betaNumerator < 0 || betaNumerator > commonDenominator){
        return false;
      }
    }else if (commonDenominator < 0){
      if (betaNumerator > 0 || betaNumerator < commonDenominator){
        return false;
      }
    }
    if (commonDenominator == 0){
      // This code wasn't in Franklin Antonio's method. It was added by Keith Woodward.
      // The lines are parallel.
      // Check if they're collinear.
      float y3LessY1 = y3-y1;
      float collinearityTestForP3 = x1*(y2-y3) + x2*(y3LessY1) + x3*(y1-y2);   // see http://mathworld.wolfram.com/Collinear.html
      // If p3 is collinear with p1 and p2 then p4 will also be collinear, since p1-p2 is parallel with p3-p4
      if (collinearityTestForP3 == 0){
        // The lines are collinear. Now check if they overlap.
        if (x1 >= x3 && x1 <= x4 || x1 <= x3 && x1 >= x4 ||
            x2 >= x3 && x2 <= x4 || x2 <= x3 && x2 >= x4 ||
            x3 >= x1 && x3 <= x2 || x3 <= x1 && x3 >= x2){
          if (y1 >= y3 && y1 <= y4 || y1 <= y3 && y1 >= y4 ||
              y2 >= y3 && y2 <= y4 || y2 <= y3 && y2 >= y4 ||
              y3 >= y1 && y3 <= y2 || y3 <= y1 && y3 >= y2){
            return true;
          }
        }
      }
      return false;
    }
    return true;
  }

  public static Vector2f getLineLineIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4) {
    float det1And2 = det(x1, y1, x2, y2);
    float det3And4 = det(x3, y3, x4, y4);
    float x1LessX2 = x1 - x2;
    float y1LessY2 = y1 - y2;
    float x3LessX4 = x3 - x4;
    float y3LessY4 = y3 - y4;
    float det1Less2And3Less4 = det(x1LessX2, y1LessY2, x3LessX4, y3LessY4);
    if (det1Less2And3Less4 == 0){
      // the denominator is zero so the lines are parallel and there's either no solution (or multiple solutions if the lines overlap) so return null.
      return null;
    }
    float x = (det(det1And2, x1LessX2,
        det3And4, x3LessX4) /
        det1Less2And3Less4);
    float y = (det(det1And2, y1LessY2,
        det3And4, y3LessY4) /
        det1Less2And3Less4);
    return new Vector2f(x, y);
  }
  protected static float det(float a, float b, float c, float d) {
    return a * d - b * c;
  }

  private static Vector2f getClosestPoint(Vector2f pt1, Vector2f pt2, Vector2f p){
    double u = ((p.getX()-pt1.getX())*(pt2.getX()-pt1.getX())+(p.getY()-pt1.getY())*(pt2.getY()-pt1.getY()))/(sqr(pt2.getX()-pt1.getX())+sqr(pt2.getY()-pt1.getY()));
    if (u > 1.0)
      return pt2.copy();
    else if (u <= 0.0)
      return pt1.copy();
    else
      return new Vector2f((int)(pt2.getX()*u+pt1.getX()*(1.0-u)+0.5), (int)(pt2.getY()*u+pt1.getY()*(1.0-u)+0.5));
  }
  private static double sqr(double x)
  {
    return x*x;
  }
}
TOP

Related Classes of framework.spacial.Line

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.