Java examples for java.lang:Math Trigonometric Function
Compute the distance between two segments.
/* // w ww. j av a2 s .co m * $Id$ * * Copyright (C) 2010-2011 Janus Core Developers * Copyright (C) 2012 St?phane GALLAND * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ public class Main{ /** Compute the distance between two segments. * * @param p position of the point. * @param s1 position of the first point of the segment. * @param s2 position of the second point of the segment. * @return the distance beetween the segments. */ public static final float distanceSegmentToSegment(Point2f s1, Point2f s2, Point2f s3, Point2f s4) { float f = getSegmentSegmentIntersectionFactor(s1, s2, s3, s4); if (!Float.isNaN(f)) { return 0f; } float d1 = distancePointToSegment(s1, s3, s4); float d2 = distancePointToSegment(s2, s3, s4); float d3 = distancePointToSegment(s3, s1, s2); float d4 = distancePointToSegment(s4, s1, s2); return MathUtil.min(d1, d2, d3, d4); } /** * Replies one position factor for the intersection point between two lines. * <p> * Let line equations for L1 and L2:<br> * <code>L1: P1 + factor1 * (P2-P1)</code><br> * <code>L2: P3 + factor2 * (P4-P3)</code><br> * If lines are intersecting, then<br> * <code>P1 + factor1 * (P2-P1) = P3 + factor2 * (P4-P3)</code> * <p> * This function computes and replies <code>factor1</code>. * * @param p1 * is the coordinates of the first point of the first segment. * @param p2 * is the coordinates of the second point of the first segment. * @param p3 * is the coordinates of the first point of the second segment. * @param p4 * is the coordinates of the second point of the second segment. * @return <code>factor1</code> or {@link Float#NaN} if no intersection. */ public static float getSegmentSegmentIntersectionFactor(Point2f p1, Point2f p2, Point2f p3, Point2f p4) { Vector2f v1 = p2.operator_minus(p1); Vector2f v2 = p4.operator_minus(p3); // determinant is zero when parallel = det(L1,L2) float det = determinant(v1, v2); if (det == 0f) return Float.NaN; // Given line equations: // Pa = P1 + ua (P2-P1), and // Pb = P3 + ub (P4-P3) // and // V = (P1-P3) // then // ua = det(L2,V) / det(L1,L2) // ub = det(L1,V) / det(L1,L2) Vector2f v3 = p1.operator_minus(p3); float u = determinant(v1, v3) / det; if (u < 0. || u > 1.) return Float.NaN; u = determinant(v2, v3) / det; return (u < 0. || u > 1.) ? Float.NaN : u; } /** Compute the distance between a point and a segment. * * @param p position of the point. * @param s1 position of the first point of the segment. * @param s2 position of the second point of the segment. * @return the distance beetween the point and the segment. */ public static final float distancePointToSegment(Point2f p, Point2f s1, Point2f s2) { float r_denomenator = (s2.getX() - s1.getX()) * (s2.getX() - s1.getX()) + (s2.getY() - s1.getY()) * (s2.getY() - s1.getY()); if (r_denomenator == 0f) return p.distance(s1); float r_numerator = (p.getX() - s1.getX()) * (s2.getX() - s1.getX()) + (p.getY() - s1.getY()) * (s2.getY() - s1.getY()); float ratio = r_numerator / r_denomenator; if (ratio <= 0.) { return (float) Math.sqrt((p.getX() - s1.getX()) * (p.getX() - s1.getX()) + (p.getY() - s1.getY()) * (p.getY() - s1.getY())); } if (ratio >= 1f) { return (float) Math.sqrt((p.getX() - s2.getX()) * (p.getX() - s2.getX()) + (p.getY() - s2.getY()) * (p.getY() - s2.getY())); } float s = ((s1.getY() - p.getY()) * (s2.getX() - s1.getX()) - (s1 .getX() - p.getX()) * (s2.getY() - s1.getY())) / r_denomenator; return (float) (Math.abs(s) * Math.sqrt(r_denomenator)); } /** Replies the min value in the given values. * * @return the min value. */ public static float min(float... values) { float min = values[0]; for (int i = 1; i < values.length; ++i) { if (min > values[i]) { min = values[i]; } } return min; } private static float determinant(Tuple2f<?> a, Tuple2f<?> b) { return a.getX() * b.getY() - b.getX() * a.getY(); } }