Skip to content

Instantly share code, notes, and snippets.

@GeePawHill
Last active September 16, 2015 17:14
Show Gist options
  • Save GeePawHill/b813e18db8e68322b803 to your computer and use it in GitHub Desktop.
Save GeePawHill/b813e18db8e68322b803 to your computer and use it in GitHub Desktop.
package org.geepawhill.whiteboard.util;
import javafx.geometry.Bounds;
import javafx.geometry.Point2D;
import javafx.scene.Node;
import javafx.scene.shape.Rectangle;
public class PointPair
{
public final double fromX;
public final double fromY;
public final double toX;
public final double toY;
public PointPair(double fromX, double fromY, double toX, double toY)
{
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
public PointPair(Point2D from, Point2D to)
{
this(from.getX(), from.getY(), to.getX(), to.getY());
}
public PointPair(Bounds bounds)
{
this(bounds.getMinX(), bounds.getMinY(), bounds.getMaxX(), bounds.getMaxY());
}
public PointPair(Node node)
{
this(node.getBoundsInParent());
}
public double width()
{
return toX-fromX;
}
public double height()
{
return toY-fromY;
}
public double centerX()
{
return (fromX + toX) / 2d;
}
public double centerY()
{
return (fromY + toY) / 2d;
}
public Point2D center()
{
return new Point2D(centerX(), centerY());
}
public PointPair offset(double amount)
{
return new PointPair(fromX - amount, fromY - amount, toX + amount, toY + amount);
}
public Compass compass()
{
int diffCase = (diffBits((int) fromX, (int) toX) << 4) + diffBits((int) fromY, (int) toY);
switch (diffCase)
{
default:
return Compass.ERROR;
case 0x01:
return Compass.S;
case 0x02:
return Compass.N;
case 0x10:
return Compass.E;
case 0x11:
return Compass.SE;
case 0x12:
return Compass.NE;
case 0x20:
return Compass.W;
case 0x21:
return Compass.SW;
case 0x22:
return Compass.NW;
}
}
private int diffBits(int from, int to)
{
// 0 means dimensions =
// 1 means from>to
// 2 means to>from
int diff = to - from;
if (diff == 0)
return 0;
else
{
if (diff > 0) return 1;
}
return 2;
}
public Point2D intersectAtPoint(PointPair other)
{
double width = width();
double height = height();
double otherWidth = other.width();
double otherHeight = other.height();
double s = (-height * (fromX - other.fromX) + width * (fromY - other.fromY)) / (-otherWidth * height + width * otherHeight);
double t = (otherWidth * (fromY - other.fromY) - otherHeight * (fromX - other.fromX)) / (-otherWidth * height + width * otherHeight);
if (s >= 0d && s <= 1d && t >= 0d && t <= 1d) { return new Point2D(fromX + (t * width), fromY + (t * height)); }
return null;
}
public PointPair fractionAnchoredAtFrom(double fraction)
{
return new PointPair(fromX,fromY, fromX+(width()*fraction), fromY+(height()*fraction));
}
public void copyToNode(Rectangle box)
{
box.setX(fromX);
box.setY(fromY);
box.setWidth(width());
box.setHeight(height());
}
}
package org.geepawhill.whiteboard.util;
import static org.junit.Assert.*;
import javafx.geometry.BoundingBox;
import javafx.geometry.Point2D;
import javafx.scene.shape.Line;
import org.geepawhill.whiteboard.util.Compass;
import org.geepawhill.whiteboard.util.PointPair;
import org.junit.Test;
public class PointPairTest
{
final double DOUBLE_ACCURACY = 0.9d; // as long as we're integer-true
@Test
public void simpleConstructor()
{
PointPair pair = new PointPair(0d,10d,100d,160d);
assertDoubles(0d,pair.fromX);
assertDoubles(10d,pair.fromY);
assertDoubles(100d,pair.toX);
assertDoubles(160d,pair.toY);
}
@Test
public void pointConstructor()
{
PointPair pair = new PointPair(new Point2D(0d,10d),new Point2D(100d,160d));
assertDoubles(0d,pair.fromX);
assertDoubles(10d,pair.fromY);
assertDoubles(100d,pair.toX);
assertDoubles(160d,pair.toY);
}
@Test
public void boundsConstructor()
{
PointPair pair = new PointPair(new BoundingBox(0d,10d,100d,150d));
assertDoubles(0d,pair.fromX);
assertDoubles(10d,pair.fromY);
assertDoubles(100d,pair.toX);
assertDoubles(160d,pair.toY);
}
@Test
public void nodeConstructor()
{
PointPair pair = new PointPair(new Line(0d,10d,100d,160d));
assertDoubles(0d,pair.fromX);
assertDoubles(10d,pair.fromY);
assertDoubles(100d,pair.toX);
assertDoubles(160d,pair.toY);
}
@Test
public void dimensions()
{
PointPair pair = new PointPair( 0d, 10d, 100d, 150d);
assertDoubles(100d,pair.width());
assertDoubles(140d,pair.height());
}
@Test
public void centers()
{
PointPair pair = new PointPair(0d,10d,100d,160d);
assertDoubles(50d,pair.centerX());
assertDoubles(85d,pair.centerY());
assertEquals(new Point2D(50d,85d),pair.center());
}
@Test
public void offsets()
{
PointPair pair = new PointPair(0d,10d,100d,160d);
assertPairs(new PointPair(-5d,5d,105d,165d),pair.offset(5d));
assertPairs(new PointPair(5d,15d,95d,155d),pair.offset(-5d));
}
@Test
public void directions()
{
assertEquals(Compass.E, new PointPair(0d,0d,100d,0d).compass());
assertEquals(Compass.W, new PointPair(100d,0d,0d,0d).compass());
assertEquals(Compass.N, new PointPair(0d,100d,0d,0d).compass());
assertEquals(Compass.S, new PointPair(0d,0d,0d,100d).compass());
assertEquals(Compass.NW, new PointPair(100d,100d,0d,0d).compass());
assertEquals(Compass.NE, new PointPair(0d,100d,100d,0d).compass());
assertEquals(Compass.SW, new PointPair(100d,0d,0d,100d).compass());
assertEquals(Compass.SE, new PointPair(0d,0d,100d,100d).compass());
}
@Test
public void simpleIntersection()
{
PointPair one = new PointPair(0d,0d,100d,200d);
PointPair other = new PointPair(0d,200d,100d,0d);
Point2D actual = one.intersectAtPoint(other);
assertDoubles(50d,actual.getX());
assertDoubles(100d,actual.getY());
}
@Test
public void noIntersection()
{
PointPair one = new PointPair(0d,0d,100d,200d);
PointPair other = new PointPair(100d,200d,100d,200d);
assertNull(one.intersectAtPoint(other));
}
@Test
public void fractionAnchoredAtFrom()
{
PointPair pair = new PointPair( 0d, 10d, 100d, 150d);
PointPair partial = pair.fractionAnchoredAtFrom(.5d);
assertDoubles(0d,partial.fromX);
assertDoubles(10d,partial.fromY);
assertDoubles(50d,partial.toX);
assertDoubles(80d,partial.toY);
}
private void assertDoubles(double expected,double actual)
{
assertEquals(expected,actual,DOUBLE_ACCURACY);
}
private void assertPairs(PointPair left,PointPair right)
{
assertDoubles(left.fromX,right.fromX);
assertDoubles(left.fromY,right.fromY);
assertDoubles(left.toX,right.toX);
assertDoubles(left.toY,right.toY);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment