package org.lemsml.jlems.viz.plot; import org.lemsml.jlems.core.logging.E; public final class Position implements XYLocation { double x; double y; boolean valid; public Position() { this(999.9, 999.9); valid = false; } public Position(XYLocation p) { set(p.getX(), p.getY()); } public Position(double px, double py) { set(px, py); } public String toString() { return "position(" + x + ", " + y + ")"; } public void set(XYLocation p) { set(p.getX(), p.getY()); } public void add(Position p) { reportInValid(); x += p.getX(); y += p.getY(); } public void subtract(Position p) { reportInValid(); x -= p.getX(); y -= p.getY(); } public void absolutize(Position porig, double scale, Position prel) { // makes thiis position absolute given relative position prel to // origin porig at scale scale. set(porig.getX() + scale * prel.getX(), porig.getY() + scale * prel.getY()); } public void relativize(Position porig, double scale, Position pabs) { // makes this positon relative given two absolute points set((pabs.getX() - porig.getX()) / scale, (pabs.getY() - porig.getY()) / scale); } private void reportInValid() { if (valid) { } else { E.warning("using a default position? " + x + " " + y); } } public void set(double px, double py) { x = px; y = py; valid = true; } public double getX() { reportInValid(); return x; } public double getY() { reportInValid(); return y; } public static Position aXPlusBY(double a, Position v, double b, Position w) { Position ret = new Position(a * v.getX() + b * w.getX(), a * v.getY() + b * w.getY()); return ret; } public void shift(double dx, double dy) { x += dx; y += dy; } public void shift(Position spos) { x += spos.getX(); y += spos.getY(); } public boolean isValid() { return valid; } public Position copy() { return new Position(this); } public double distanceFrom(Position p) { double dx = p.getX() - x; double dy = p.getY() - y; return Math.sqrt(dx*dx + dy*dy); } public double distanceFromOrigin() { return Math.sqrt(x*x + y*y); } public Position getRelativeToBoxCenter(double[] xyxy) { double cx = (xyxy[2] + xyxy[0]) / 2; double dx = (xyxy[2] - xyxy[0]) / 2; double cy = (xyxy[3] + xyxy[1]) / 2; double dy = (xyxy[3] - xyxy[1]) / 2; return new Position((x - cx) / dx, (y - cy) / dy); } public void setX(double d) { x = d; } public void setY(double d) { y = d; } public static Position midpoint(Position pa, Position pb) { return new Position(0.5 * (pa.x + pb.x), 0.5*(pa.y + pb.y)); } public void rotateBy(double rad) { double c = Math.cos(rad); double s = Math.sin(rad); rotateCosSin(c, s); } private void rotateCosSin(double c, double s) { double xr = c * x - s * y; double yr = s * x + c * y; x = xr; y = yr; } public void rotateTo(Direction dir) { double c = dir.getCosine(); double s = dir.getSine(); rotateCosSin(c, s); } public void rotateAbout(Position pcen, double rad) { double c = Math.cos(rad); double s = Math.sin(rad); double cx = pcen.getX(); double cy = pcen.getY(); double dx = x - cx; double dy = y - cy; x = cx + c * dx - s * dy; y = cy + s * dx + c * dy; } }