/* * Copyright (c) 2010 Georgios Migdos <cyberpython@gmail.com> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ package org.geogebra.common.kernel.discrete.geom; import java.io.PrintStream; import java.util.Iterator; import java.util.List; /** * * @author cyberpython */ public class LineAndPointUtils { private static double errorTolerance = 0.001; public static double getErrorTolerance() { return LineAndPointUtils.errorTolerance; } public static void setErrorTolerance(double errorTolerance) { LineAndPointUtils.errorTolerance = errorTolerance; } public static Point2D computeIntersectionPoint(Segment2D s1, Segment2D s2) { if ((s1 == null) || (s2 == null)) { return null; } Point2D line1Point1 = s1.getStart(); Point2D line1Point2 = s1.getEnd(); Point2D line2Point1 = s2.getStart(); Point2D line2Point2 = s2.getEnd(); Point2D intersectionPoint = findIntersectionPointOfLines(line1Point1, line1Point2, line2Point1, line2Point2); if (isOnSegment(intersectionPoint, line1Point1, line1Point2) && isOnSegment(intersectionPoint, line2Point1, line2Point2)) { return intersectionPoint; } return null; } public static boolean isOnSegment(Point2D p, Point2D segmentPoint1, Point2D segmentPoint2) { if (p == null) { return false; } Double x0 = p.getX(); Double y0 = p.getY(); Double x1 = segmentPoint1.getX(); Double y1 = segmentPoint1.getY(); Double x2 = segmentPoint2.getX(); Double y2 = segmentPoint2.getY(); Double maxX = Math.max(x1, x2); Double maxY = Math.max(y1, y2); Double minX = Math.min(x1, x2); Double minY = Math.min(y1, y2); if ((x0 - minX >= -errorTolerance) && (x0 - maxX <= errorTolerance) && (y0 - minY >= -errorTolerance) && (y0 - maxY <= errorTolerance)) { return true; } return false; } public static Point2D findIntersectionPointOfLines(Point2D line1Point1, Point2D line1Point2, Point2D line2Point1, Point2D line2Point2) { Double line1X1 = line1Point1.getX(); Double line1Y1 = line1Point1.getY(); Double line1X2 = line1Point2.getX(); Double line1Y2 = line1Point2.getY(); Double line2X1 = line2Point1.getX(); Double line2Y1 = line2Point1.getY(); Double line2X2 = line2Point2.getX(); Double line2Y2 = line2Point2.getY(); Double line1Lambda; Double line2Lambda; if (line1X2.compareTo(line1X1) == 0) { line1Lambda = null; } else { line1Lambda = (line1Y2 - line1Y1) / (line1X2 - line1X1); // System.out.println("line1 -> " + line1Lambda); } if (line2X2.compareTo(line2X1) == 0) { line2Lambda = null; } else { line2Lambda = (line2Y2 - line2Y1) / (line2X2 - line2X1); // System.out.println("line2 -> " + line2Lambda); } // Both lines are vertical: if ((line1Lambda == null) && (line2Lambda == null)) { return null; } // Lines are parallel to each other: if ((line1Lambda != null) && (line2Lambda != null)) { if (line1Lambda.compareTo(line2Lambda) == 0) { return null; } } Double x0; Double y0; if (line1Lambda == null) { // Line 1 is vertical x0 = line1X1; y0 = line2Lambda * (x0 - line2X1) + line2Y1; } else if (line2Lambda == null) { // Line 2 is vertical x0 = line2X1; y0 = line1Lambda * (x0 - line1X1) + line1Y1; } else { // Okay, let's find the intersection: x0 = ((line1Lambda * line1X1) - line1Y1 - (line2Lambda * line2X1) + line2Y1) / (line1Lambda - line2Lambda); y0 = line1Lambda * (x0 - line1X1) + line1Y1; } return new Point2D(x0, y0); } public static boolean pointsAreEqual(Point2D p1, Point2D p2) { Double x1 = p1.getX(); Double y1 = p1.getY(); Double x2 = p2.getX(); Double y2 = p2.getY(); if ((Math.abs(y2 - y1) <= errorTolerance) && (Math.abs(x2 - x1) <= errorTolerance)) { return true; } return false; } public static void printPointsList(List<Point2D> points, PrintStream out) { boolean first = true; for (Iterator<Point2D> it = points.iterator(); it.hasNext();) { Point2D point2D = it.next(); if (first) { first = false; } else { out.print(" -> "); } out.print(point2D.toString()); } out.println(); } }