use of com.ait.lienzo.client.core.types.Point2DArray in project lienzo-core by ahome-it.
the class Geometry method findIntersection.
/**
* Finds intersecting point from the center of a path
* @param x
* @param y
* @param path
* @return the path's intersection point, or null if there's no intersection point
*/
public static Point2D findIntersection(final int x, final int y, final MultiPath path) {
final Point2D pointerPosition = new Point2D(x, y);
final BoundingBox box = path.getBoundingBox();
final Point2D center = findCenter(box);
// length just needs to ensure the c to xy is outside of the path
final double length = box.getWidth() + box.getHeight();
final Point2D projectionPoint = getProjection(center, pointerPosition, length);
final Point2DArray points = new Point2DArray();
points.push(center);
points.push(projectionPoint);
final Set<Point2D>[] intersects = Geometry.getCardinalIntersects(path, points);
Point2D nearest = null;
for (final Set<Point2D> set : intersects) {
double nearesstDistance = length;
if ((set != null) && !set.isEmpty()) {
for (final Point2D p : set) {
final double currentDistance = p.distance(pointerPosition);
if (currentDistance < nearesstDistance) {
nearesstDistance = currentDistance;
nearest = p;
}
}
}
}
return nearest;
}
use of com.ait.lienzo.client.core.types.Point2DArray in project lienzo-core by ahome-it.
the class Geometry method getCardinals.
/**
* Returns cardinal points for a given bounding box
*
* @param box the bounding box
* @return [C, N, NE, E, SE, S, SW, W, NW]
*/
public static final Point2DArray getCardinals(final BoundingBox box, final Direction[] requestedCardinals) {
final Set<Direction> set = new HashSet<>(Arrays.asList(requestedCardinals));
final Point2DArray points = new Point2DArray();
final Point2D c = findCenter(box);
final Point2D n = new Point2D(c.getX(), box.getY());
final Point2D e = new Point2D(box.getX() + box.getWidth(), c.getY());
final Point2D s = new Point2D(c.getX(), box.getY() + box.getHeight());
final Point2D w = new Point2D(box.getX(), c.getY());
final Point2D sw = new Point2D(w.getX(), s.getY());
final Point2D se = new Point2D(e.getX(), s.getY());
final Point2D ne = new Point2D(e.getX(), n.getY());
final Point2D nw = new Point2D(w.getX(), n.getY());
points.push(c);
if (set.contains(Direction.NORTH)) {
points.push(n);
}
if (set.contains(Direction.NORTH_EAST)) {
points.push(ne);
}
if (set.contains(Direction.EAST)) {
points.push(e);
}
if (set.contains(Direction.SOUTH_EAST)) {
points.push(se);
}
if (set.contains(Direction.SOUTH)) {
points.push(s);
}
if (set.contains(Direction.SOUTH_WEST)) {
points.push(sw);
}
if (set.contains(Direction.WEST)) {
points.push(w);
}
if (set.contains(Direction.NORTH_WEST)) {
points.push(nw);
}
return points;
}
use of com.ait.lienzo.client.core.types.Point2DArray in project lienzo-core by ahome-it.
the class Geometry method getCardinalIntersects.
public static Point2DArray getCardinalIntersects(final PathPartList path, final Direction[] requestedCardinals) {
final Point2DArray cardinals = getCardinals(path.getBoundingBox(), requestedCardinals);
@SuppressWarnings("unchecked") final Set<Point2D>[] // c is removed, so -1
intersections = new Set[cardinals.size()];
getCardinalIntersects(path, cardinals, intersections, true);
return removeInnerPoints(cardinals.get(0), intersections);
}
use of com.ait.lienzo.client.core.types.Point2DArray in project lienzo-core by ahome-it.
the class Geometry method getPathIntersect.
/**
* Finds the intersection of the connector's end segment on a path.
* @param connection
* @param path
* @param c
* @param pointIndex
* @return
*/
public static Point2D getPathIntersect(final WiresConnection connection, final MultiPath path, final Point2D c, final int pointIndex) {
final Point2DArray plist = connection.getConnector().getLine().getPoint2DArray();
Point2D p = plist.get(pointIndex).copy();
final Point2D offsetP = path.getComputedLocation();
p.offset(-offsetP.getX(), -offsetP.getY());
// p may be within the path boundary, so work of a vector that guarantees a point outside
final double width = path.getBoundingBox().getWidth();
if (c.equals(p)) {
// this happens with the magnet is over the center of the opposite shape
// so either the shapes are horizontall or vertically aligned.
// this means we can just take the original centre point for the project
// without this the project throw an error as you cannot unit() something of length 0,0
p.offset(offsetP.getX(), offsetP.getY());
}
try {
p = getProjection(c, p, width);
final Set<Point2D>[] set = Geometry.getCardinalIntersects(path, new Point2DArray(c, p));
final Point2DArray points = Geometry.removeInnerPoints(c, set);
return (points.size() > 1) ? points.get(1) : null;
} catch (final Exception e) {
return null;
}
}
use of com.ait.lienzo.client.core.types.Point2DArray in project lienzo-core by ahome-it.
the class Geometry method intersectLineArcTo.
/**
* Returns the points the line intersects the arcTo path. Note that as arcTo's points are actually two
* lines form p1 at a tangent to the arc's circle, it can draw a line from p0 to the start of the arc
* which forms another potential intersect point.
*
* @param a0 start of the line
* @param a1 end of the line
* @param p0 p0 to p1 forms one line on the arc's circle tangent
* @param p1 p1 to p2 forms one line on the arc's circle tangent
* @param p2 p1 to p2 forms one line on the arc's circle tangent
* @param r the radius of the arc
* @return
*/
public static final Point2DArray intersectLineArcTo(final Point2D a0, final Point2D a1, final Point2D p0, final Point2D p1, final Point2D p2, final double r) {
final Point2DArray arcPoints = getCanvasArcToPoints(p0, p1, p2, r);
final Point2DArray circleIntersectPoints = intersectLineCircle(a0, a1, arcPoints.get(1), r);
final Point2DArray arcIntersectPoints = new Point2DArray();
Point2D ps = arcPoints.get(0);
final Point2D pc = arcPoints.get(1);
Point2D pe = arcPoints.get(2);
if (!ps.equals(p0)) {
// canvas draws a line form p0 to p1, this is a new potential intersection point
final Point2D t = intersectLineLine(p0, ps, a0, a1);
if (t != null) {
arcIntersectPoints.push(t);
}
}
if ((pe.sub(pc)).crossScalar((ps.sub(pc))) < 0) {
// reverse to make counterclockwise
final Point2D t = pe;
pe = ps;
ps = t;
}
// This means a simple bounding box check on the intersect points and the line can be used.
if (circleIntersectPoints.size() > 0) {
final Point2D t = circleIntersectPoints.get(0);
final boolean within = intersectPointWithinBounding(t, a0, a1);
// check which points are on the arc. page 4 http://www.geometrictools.com/Documentation/IntersectionLine2Circle2.pdf
if (within && (t.sub(ps).dot(pe.sub(ps).perpendicular()) >= 0)) {
arcIntersectPoints.push(t);
}
}
if (circleIntersectPoints.size() == 2) {
final Point2D t = circleIntersectPoints.get(1);
final boolean within = intersectPointWithinBounding(t, a0, a1);
// check which points are on the arc. page 4 http://www.geometrictools.com/Documentation/IntersectionLine2Circle2.pdf
if (within && (t.sub(ps).dot(pe.sub(ps).perpendicular()) >= 0)) {
arcIntersectPoints.push(t);
}
}
return arcIntersectPoints;
}
Aggregations