Package net.phys2d.raw.shapes

Source Code of net.phys2d.raw.shapes.Line

/*
* Phys2D - a 2D physics engine based on the work of Erin Catto.
*
* This source is provided under the terms of the BSD License.
*
* Copyright (c) 2006, Phys2D
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or
* without modification, are permitted provided that the following
* conditions are met:
*
*  * Redistributions of source code must retain the above
*    copyright notice, this list of conditions and the
*    following disclaimer.
*  * Redistributions in binary form must reproduce the above
*    copyright notice, this list of conditions and the following
*    disclaimer in the documentation and/or other materials provided
*    with the distribution.
*  * Neither the name of the Phys2D/New Dawn Software nor the names of
*    its contributors may be used to endorse or promote products
*    derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*/
package net.phys2d.raw.shapes;

import net.phys2d.math.ROVector2f;
import net.phys2d.math.Vector2f;

/**
* 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 strictfp class Line extends AbstractShape implements DynamicShape {
  /** The start point of the line */
  private ROVector2f start;
  /** The end point of the line */
  private ROVector2f end;
  /** The vector between the two points */
  private Vector2f vec;
  /** The length of the line squared */
  private float lenSquared;
 
  /** Temporary storage - declared globally to reduce GC */
  private Vector2f loc = new Vector2f(0,0);
  /** Temporary storage - declared globally to reduce GC */
  private Vector2f v = new Vector2f(0,0);
  /** Temporary storage - declared globally to reduce GC */
  private Vector2f v2 = new Vector2f(0,0);
  /** Temporary storage - declared globally to reduce GC */
  private Vector2f proj = new Vector2f(0,0);

  /** Temporary storage - declared globally to reduce GC */
  private Vector2f closest = new Vector2f(0,0);
  /** Temporary storage - declared globally to reduce GC */
  private Vector2f other = new Vector2f(0,0);

  /** True if this line blocks on the outer edge */
  private boolean outerEdge = true;
  /** True if this line blocks on the inner edge */
  private boolean innerEdge = true;
 
  /**
   * 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
   * @param inner True if this line blocks on it's inner edge
   * @param outer True if this line blocks on it's outer edge
   */
  public Line(float x, float y, boolean inner, boolean outer) {
    this(0,0,x,y);
   
    setBlocksInnerEdge(inner);
    setBlocksOuterEdge(outer);
  }

  /**
   * 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(x,y,true,true);
  }
 
  /**
   * 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 new line based on two points
   *
   * @param start The start point
   * @param end The end point
   */
  public Line(ROVector2f start, ROVector2f end) {
    super();
   
//    float width = Math.abs(end.getX()-start.getX());
//    float height = Math.abs(end.getY()-start.getY());
//    float xoffset = width/2;
//    float yoffset = height/2;
//    if (width < 10) {
//      width = 10;
//    }
//    if (height < 10) {
//      height = 50;
//    }
//    if (end.getY() < start.getY()) {
//      yoffset = -yoffset;
//    }
//    if (end.getX() < start.getX()) {
//      xoffset = -xoffset;
//    }
    //TODO: do this properly!
    float radius = Math.max(start.length(), end.length());
    bounds = new AABox(0,0,radius*2,radius*2);
   
    set(start,end);
  }
 
  /**
   * Check if this line blocks the inner side (for want of a better term)
   *
   * @return True if this line blocks the inner side
   */
  public boolean blocksInnerEdge() {
    return innerEdge;
  }
 
  /**
   * Indicate if this line blocks on it's inner edge
   *
   * @param innerEdge True if this line blocks on it's inner edge
   */
  public void setBlocksInnerEdge(boolean innerEdge) {
    this.innerEdge = innerEdge;
  }

  /**
   * Check if this line blocks the outer side (for want of a better term)
   *
   * @return True if this line blocks the outer side
   */
  public boolean blocksOuterEdge() {
    return outerEdge;
  }

  /**
   * Indicate if this line blocks on it's outer edge
   *
   * @param outerEdge True if this line blocks on it's outer edge
   */
  public void setBlocksOuterEdge(boolean outerEdge) {
    this.outerEdge = outerEdge;
  }
 
  /**
   * Get the start point of the line
   *
   * @return The start point of the line
   */
  public ROVector2f getStart() {
    return start;
  }

  /**
   * Get the end point of the line
   *
   * @return The end point of the line
   */
  public ROVector2f 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(ROVector2f start, ROVector2f end) {
    this.start = start;
    this.end = end;
   
    vec = new Vector2f(end);
    vec.sub(start);
   
    lenSquared = vec.length();
    lenSquared *= lenSquared;
  }
 
  /**
   * 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();
  }
 
  /**
   * 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(ROVector2f point) {
    return (float) Math.sqrt(distanceSquared(point));
  }
 
  /**
   * 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(ROVector2f point) {
    getClosestPoint(point, closest);
    closest.sub(point);
   
    float result = closest.lengthSquared();
   
    return result;
  }
 
  /**
   * 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(ROVector2f point, Vector2f result) {
    loc.set(point);
    loc.sub(start);
   
    v.set(vec);
    v2.set(vec);
    v2.scale(-1);
   
    v.normalise();
    loc.projectOntoUnit(v, proj);
    if (proj.lengthSquared() > vec.lengthSquared()) {
      result.set(end);
      return;
    }
    proj.add(start);
   
    other.set(proj);
    other.sub(end);
    if (other.lengthSquared() > vec.lengthSquared()) {
      result.set(start);
      return;
    }
   
    result.set(proj);
    return;
  }

  /**
   * @see net.phys2d.raw.shapes.Shape#getSurfaceFactor()
   */
  public float getSurfaceFactor() {
    return lengthSquared() / 2;
  }
 
  /**
   * Get a line starting a x,y and ending offset from the current
   * end point. Curious huh?
   *
   * @param displacement The displacement of the line
   * @param rotation The rotation of the line in radians
   * @return The newly created line
   */
  public Line getPositionedLine(ROVector2f displacement, float rotation) {
    Vector2f[] verts = getVertices(displacement, rotation);
    Line line = new Line(verts[0], verts[1]);
   
    return line;
  }
 
  /**
   * Return a translated and rotated line.
   *
   * @param displacement The displacement of the line
   * @param rotation The rotation of the line in radians
   * @return The two endpoints of this line
   */
  public Vector2f[] getVertices(ROVector2f displacement, float rotation) {
    float cos = (float) Math.cos(rotation);
    float sin = (float) Math.sin(rotation);
   
    Vector2f[] endPoints = new Vector2f[2];
    endPoints[0] = new Vector2f(//getX1(), getY1());
        getX1() * cos - getY1() * sin,
        getY1() * cos + getX1() * sin);
    endPoints[0].add(displacement);
    endPoints[1] = new Vector2f(//getX2(), getY2());
        getX2() * cos - getY2() * sin,
        getY2() * cos + getX2() * sin);
    endPoints[1].add(displacement);
   
    return endPoints;
  }
 
  /**
   * Move this line a certain amount
   *
   * @param v The amount to move the line
   */
  public void move(ROVector2f v) {
    Vector2f temp = new Vector2f(start);
    temp.add(v);
    start = temp;
    temp = new Vector2f(end);
    temp.add(v);
    end = temp;
  }
 
  /**
   * @see java.lang.Object#toString()
   */
  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) {
    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 null;
    }
   
    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;
   
    float u = ua;
   
    float ix = start.getX() + (u * (end.getX() - start.getX()));
    float iy = start.getY() + (u * (end.getY() - start.getY()));
   
    return new Vector2f(ix,iy);
  }
 
}
TOP

Related Classes of net.phys2d.raw.shapes.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.