📄 numerics.java
字号:
/* * $RCSfile: Numerics.java,v $ * * Copyright (c) 2007 Sun Microsystems, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistribution of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * - Redistribution in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * Neither the name of Sun Microsystems, Inc. or the names of * contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * This software is provided "AS IS," without a warranty of any * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY * EXCLUDED. SUN MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL * NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF * USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR ITS * DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE FOR * ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, * CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND * REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR * INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGES. * * You acknowledge that this software is not designed, licensed or * intended for use in the design, construction, operation or * maintenance of any nuclear facility. * * $Revision: 1.4 $ * $Date: 2007/02/09 17:20:20 $ * $State: Exp $ */// ----------------------------------------------------------------------//// The reference to Fast Industrial Strength Triangulation (FIST) code// in this release by Sun Microsystems is related to Sun's rewrite of// an early version of FIST. FIST was originally created by Martin// Held and Joseph Mitchell at Stony Brook University and is// incorporated by Sun under an agreement with The Research Foundation// of SUNY (RFSUNY). The current version of FIST is available for// commercial use under a license agreement with RFSUNY on behalf of// the authors and Stony Brook University. Please contact the Office// of Technology Licensing at Stony Brook, phone 631-632-9009, for// licensing information.//// ----------------------------------------------------------------------package com.sun.j3d.utils.geometry;import java.io.*;import java.util.*;import javax.vecmath.*;class Numerics { static double max3(double a, double b, double c) { return (((a) > (b)) ? (((a) > (c)) ? (a) : (c)) : (((b) > (c)) ? (b) : (c))); } static double min3(double a, double b, double c) { return (((a) < (b)) ? (((a) < (c)) ? (a) : (c)) : (((b) < (c)) ? (b) : (c))); } static boolean lt(double a, double eps) { return ((a) < -eps); } static boolean le(double a, double eps) { return (a <= eps); } static boolean ge(double a, double eps) { return (!((a) <= -eps)); } static boolean eq(double a, double eps) { return (((a) <= eps) && !((a) < -eps)); } static boolean gt(double a, double eps) { return !((a) <= eps); } static double baseLength(Tuple2f u, Tuple2f v) { double x, y; x = (v).x - (u).x; y = (v).y - (u).y; return Math.abs(x) + Math.abs(y); } static double sideLength(Tuple2f u, Tuple2f v) { double x, y; x = (v).x - (u).x; y = (v).y - (u).y; return x * x + y * y; } /** * This checks whether i3, which is collinear with i1, i2, is * between i1, i2. note that we rely on the lexicographic sorting of the * points! */ static boolean inBetween(int i1, int i2, int i3) { return ((i1 <= i3) && (i3 <= i2)); } static boolean strictlyInBetween(int i1, int i2, int i3) { return ((i1 < i3) && (i3 < i2)); } /** * this method computes the determinant det(points[i],points[j],points[k]) * in a consistent way. */ static double stableDet2D(Triangulator triRef, int i, int j, int k) { double det; Point2f numericsHP, numericsHQ, numericsHR; // if((triRef.inPointsList(i)==false)||(triRef.inPointsList(j)==false)|| // (triRef.inPointsList(k)==false)) // System.out.println("Numerics.stableDet2D Not inPointsList " + i + " " + j // + " " + k); if ((i == j) || (i == k) || (j == k)) { det = 0.0; } else { numericsHP = triRef.points[i]; numericsHQ = triRef.points[j]; numericsHR = triRef.points[k]; if (i < j) { if (j < k) /* i < j < k */ det = Basic.det2D(numericsHP, numericsHQ, numericsHR); else if (i < k) /* i < k < j */ det = -Basic.det2D(numericsHP, numericsHR, numericsHQ); else /* k < i < j */ det = Basic.det2D(numericsHR, numericsHP, numericsHQ); } else { if (i < k) /* j < i < k */ det = -Basic.det2D(numericsHQ, numericsHP, numericsHR); else if (j < k) /* j < k < i */ det = Basic.det2D(numericsHQ, numericsHR, numericsHP); else /* k < j < i */ det = -Basic.det2D(numericsHR, numericsHQ, numericsHP); } } return det; } /** * Returns the orientation of the triangle. * @return +1 if the points i, j, k are given in CCW order; * -1 if the points i, j, k are given in CW order; * 0 if the points i, j, k are collinear. */ static int orientation(Triangulator triRef, int i, int j, int k) { int ori; double numericsHDet; numericsHDet = stableDet2D(triRef, i, j, k); // System.out.println("orientation : numericsHDet " + numericsHDet); if (lt(numericsHDet, triRef.epsilon)) ori = -1; else if (gt(numericsHDet, triRef.epsilon)) ori = 1; else ori = 0; return ori; } /** * This method checks whether l is in the cone defined by i, j and j, k */ static boolean isInCone(Triangulator triRef, int i, int j, int k, int l, boolean convex) { boolean flag; int numericsHOri1, numericsHOri2; // if((triRef.inPointsList(i)==false)||(triRef.inPointsList(j)==false)|| // (triRef.inPointsList(k)==false)||(triRef.inPointsList(l)==false)) // System.out.println("Numerics.isInCone Not inPointsList " + i + " " + j // + " " + k + " " + l); flag = true; if (convex) { if (i != j) { numericsHOri1 = orientation(triRef, i, j, l); // System.out.println("isInCone : i != j, numericsHOri1 = " + numericsHOri1); if (numericsHOri1 < 0) flag = false; else if (numericsHOri1 == 0) { if (i < j) { if (!inBetween(i, j, l)) flag = false; } else { if (!inBetween(j, i, l)) flag = false; } } } if ((j != k) && (flag == true)) { numericsHOri2 = orientation(triRef, j, k, l); // System.out.println("isInCone : ((j != k) && (flag == true)), numericsHOri2 = " + // numericsHOri2); if (numericsHOri2 < 0) flag = false; else if (numericsHOri2 == 0) { if (j < k) { if (!inBetween(j, k, l)) flag = false; } else { if (!inBetween(k, j, l)) flag = false; } } } } else { numericsHOri1= orientation(triRef, i, j, l); if (numericsHOri1 <= 0) { numericsHOri2 = orientation(triRef, j, k, l); if (numericsHOri2 < 0) flag = false; } } return flag; } /** * Returns convex angle flag. * @return 0 ... if angle is 180 degrees <br> * 1 ... if angle between 0 and 180 degrees <br> * 2 ... if angle is 0 degrees <br> * -1 ... if angle between 180 and 360 degrees <br> * -2 ... if angle is 360 degrees <br> */ static int isConvexAngle(Triangulator triRef, int i, int j, int k, int ind) { int angle; double numericsHDot; int numericsHOri1; Point2f numericsHP, numericsHQ; // if((triRef.inPointsList(i)==false)||(triRef.inPointsList(j)==false)|| // (triRef.inPointsList(k)==false)) // System.out.println("Numerics.isConvexAngle: Not inPointsList " + i + " " + j // + " " + k); if (i == j) { if (j == k) { // all three vertices are identical; we set the angle to 1 in // order to enable clipping of j. return 1; } else { // two of the three vertices are identical; we set the angle to 1 // in order to enable clipping of j. return 1; } } else if (j == k) { // two vertices are identical. we could either determine the angle // by means of yet another lengthy analysis, or simply set the // angle to -1. using -1 means to err on the safe side, as all the // incarnations of this vertex will be clipped right at the start // of the ear-clipping algorithm. thus, eventually there will be no // other duplicates at this vertex position, and the regular // classification of angles will yield the correct answer for j. return -1; } else { numericsHOri1 = orientation(triRef, i, j, k); // System.out.println("i " + i + " j " + j + " k " + k + " ind " + ind + // ". In IsConvexAngle numericsHOri1 is " + // numericsHOri1); if (numericsHOri1 > 0) { angle = 1; } else if (numericsHOri1 < 0) { angle = -1; } else { // 0, 180, or 360 degrees. numericsHP = new Point2f(); numericsHQ = new Point2f(); Basic.vectorSub2D(triRef.points[i], triRef.points[j], numericsHP); Basic.vectorSub2D(triRef.points[k], triRef.points[j], numericsHQ); numericsHDot = Basic.dotProduct2D(numericsHP, numericsHQ); if (numericsHDot < 0.0) { // 180 degrees. angle = 0; } else { // 0 or 360 degrees? this cannot be judged locally, and more // work is needed. angle = spikeAngle(triRef, i, j, k, ind); // System.out.println("SpikeAngle return is "+ angle); } } } return angle; } /** * This method checks whether point i4 is inside of or on the boundary * of the triangle i1, i2, i3.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -