Package hermes.hshape

Source Code of hermes.hshape.HRectangle

package hermes.hshape;

import hermes.Hermes;
import processing.core.PApplet;
import processing.core.PVector;
import static hermes.HermesMath.*;

/**
* Represents an axis-aligned bounding rectangle.
*/
public class HRectangle extends HShape {

  private PVector _min, _max;

  public static int mode = 0;

  /**
   * Creates a new Rectangle based on current rectMode.
   * <p>
   * Default - a and b define the upper left corner, and c and d are width and height,
   * see Processing reference on rectMode() for details on other modes.
   * @param a
   * @param b
   * @param c
   * @param d
   */
  public HRectangle(float a, float b, float c, float d) {
    super(new PVector(a,b,0));
    PApplet p = Hermes.getPApplet();
    if(p != null) {
      switch(p.g.rectMode) {
      case PApplet.CORNER:
        _min = zeroVector();
        _max = new PVector(c,d);
        break;
      case PApplet.CENTER:
        _min = new PVector(-c/2,-d/2);
        _max = new PVector(c/2,d/2);
        break;
      case PApplet.CORNERS:
        _min = zeroVector();
        _max = new PVector(c-a,d-b);
        break;
      case PApplet.RADIUS:
        _min = new PVector(-c,-d,0);
        _max = new PVector(c,d,0);
        break;
      }
    } else {
      _min = zeroVector();
      _max = new PVector(c,d);
    }
  }
 
  /**
   * Creates a new Rectangle based on current rectMode.
   * <p>
   * Default - ab.x and ab.y define the upper left corner, and c and d are width and height,
   * see Processing reference on rectMode() for details on other modes.
   * @param ab
   * @param c
   * @param d
   */
  public HRectangle(PVector ab, float c, float d) {
    this(ab.x, ab.y, c, d);
  }
 
  /**
   * Creates a new Rectangle based on current rectMode.
   * <p>
   * Default - ab.x and ab.y define the upper left corner, and cd.x and cd.y are width and height
   * see Processing reference on rectMode() for details on other modes
   * @param ab
   * @param cd
   */
  public HRectangle(PVector ab, PVector cd) {
    this(ab.x, ab.y, cd.x, cd.y);
  }
 
  /**
   * Creates a new Rectangle.
   * <p>
   * Directly assigns fields, does not link with rectMode.
   * @param position - position of rectangle
   * @param min - location of top left corner in relation to position
   * @param max - location of bottom right corner in relation to position
   */
  public HRectangle(PVector position, PVector min, PVector max) {
    super(position);
    _min = min;
    _max = max;
  }

  /**
   * @return Position of corner with lowest x,y values in Rectangle coordinates (shape's position is (0,0)).
   */
  public PVector getMin() {
    return _min;
  }

  /**
   * @return Position of corner with highest x,y values in Rectangle coordinates (shape's position is (0,0)).
   */
  public PVector getMax() {
    return _max;
  }

  /**
   * @return Position of corner with lowest x,y values in world coordinates.
   */
  public PVector getAbsMin() {
    return PVector.add(_min, _position);
  }
 
  /**
   * @return Position of corner with highest x,y values in world coordinates.
   */
  public PVector getAbsMax() {
    return PVector.add(_max, _position);
  }
 
  public float getWidth() {
    return _max.x - _min.x;
  }
 
  public float getHeight() {
    return _max.y - _min.y;
  }
 
  /**
   * @return  The absolute position of the rectangle's geometric center.
   */
  public PVector getCenter() {
    PVector center = PVector.add(_max, _min);
    center.mult(0.5f);
    center.add(_position);
    return center;
  }

  /**
   * Scales the rectangle's width and height about its position.
   * @param xScale  the x-axis scale factor
   * @param yScale  the y-axis scale factor
   */
  public void scale(float xScale, float yScale) {
    assert xScale > 0 : "scale: xScale must be greater than zero";
    assert yScale > 0 : "scale: yScale must be greater than zero";

    _min.x *= xScale;
    _max.x *= xScale;
    _min.y *= yScale;
    _max.y *= yScale;
  }

  @Override
  public PVector projectionVector(HShape other) {
    assert other != null : "Rectangle.projectionVector: other must be a valid rectangle";
    PVector opposite = other.projectionVector(this);
    return opposite == null ? null : reverse(opposite);
  }

  @Override
  public PVector projectionVector(HCircle other) {
    PVector opposite = other.projectionVector(this);
    return opposite == null ? null : reverse(opposite);
  }

  @Override
  public PVector projectionVector(HPolygon other) {
    PVector opposite = other.projectionVector(this);
    return opposite == null ? null : reverse(opposite);
  }

  @Override
  public PVector projectionVector(HRectangle other) {
    if(other == this// no self-projection
      return null;
    // calculate the distance between rect centers
    PVector center1 = getCenter();
    PVector center2 = other.getCenter();
    float xDist = center1.x - center2.x;
    float yDist = center1.y - center2.y;
    // the projection is distance minus combined side length
    float xProject = Math.abs(xDist) - (_max.x - _min.x + other._max.x - other._min.x)/2;
    float yProject = Math.abs(yDist) - (_max.y - _min.y + other._max.y - other._min.y)/2;
    // they collide if they overlap on both axes
    if( xProject > 0 || yProject > 0)
      return null;
    // the projection vector is the smallest projection, in direction opposite the distance vector
    return (xProject > yProject ?
        new PVector(xProject * sign(xDist), 0.0f) :
          new PVector(0.0f, yProject * sign(yDist)));
 

  @Override
  public HRectangle getBoundingBox() {
    return this;
  }
 
  /**
   * Whether this rectangle completely encloses another
   * (no part of other protrudes from this).
   * @param other    the other rectangle
   * @return      whether it is completely contained
   */
  public boolean contains(HRectangle other) {
    float minX1 = getAbsMin().x;
    float minY1 = getAbsMin().y;
    float maxX1 = getAbsMax().x;
    float maxY1 = getAbsMax().y;
    float minX2 = other.getAbsMin().x;
    float minY2 = other.getAbsMin().y;
    float maxX2 = other.getAbsMax().x;
    float maxY2 = other.getAbsMax().y;
   
    return minX1 <= minX2 && minY1 <= minY2 &&
        maxX1 >= maxX2 && maxY1 >= maxY2;
  }

  @Override
  public boolean contains(float x, float y) {
    return x >= getAbsMin().x && y >= getAbsMin().y && x <= getAbsMax().x && y <= getAbsMax().y;
  }
 
  @Override
  public boolean contains(PVector point) {
    return contains(point.x, point.y);
  }
 
  @Override
  public void draw() {
    Hermes.getPApplet().rect(_min.x,_min.y,_max.x-_min.x,_max.y-_min.y);
  }

  @Override
  public String toString() {
    return "Position:" + _position + "\nMin:" + _min + "\nMax:" + _max;
  }
}
TOP

Related Classes of hermes.hshape.HRectangle

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.