protected static double[] getInitialBinormal(double[][] polygon, int metric) { int n = polygon.length; double[] B = new double[4]; for (int i = 1; i < n - 1; ++i) { Pn.polarize(B, P3.planeFromPoints(null, polygon[i - 1], polygon[i], polygon[i + 1]), metric); if (Rn.euclideanNormSquared(B) > 10E-16) return B; } B = new double[] {Math.random(), Math.random(), Math.random(), 1.0}; return Pn.polarizePlane(null, P3.planeFromPoints(null, B, polygon[1], polygon[2]), metric); }
private final void unionVectors(DataList dl) { double[][] data = dl.toDoubleArrayArray(null); double[][] tmpVec = new double[2][3]; int length = data.length; if (length == 0) return; int vectorLength = data[0].length; if (vectorLength < 3 || vectorLength > 4) return; Rn.matrixTimesVector(data, currentTrafo, data); try { if (vectorLength == 4) { Pn.calculateBounds(tmpVec, data); } else if (vectorLength == 3) { Rn.calculateBounds(tmpVec, data); } } catch (IllegalStateException e) { e.printStackTrace(); } if (Rn.isNan(tmpVec[0]) || Rn.isNan(tmpVec[1])) return; bound.xmin = Math.min(bound.xmin, tmpVec[0][0]); bound.xmax = Math.max(bound.xmax, tmpVec[1][0]); bound.ymin = Math.min(bound.ymin, tmpVec[0][1]); bound.ymax = Math.max(bound.ymax, tmpVec[1][1]); bound.zmin = Math.min(bound.zmin, tmpVec[0][2]); bound.zmax = Math.max(bound.zmax, tmpVec[1][2]); }
public static void calculateAndSetNormalVectorsForCurve(IndexedLineSet ils) { double[][] polygon = ils.getVertexAttributes(Attribute.COORDINATES).toDoubleArrayArray(null); int n = polygon.length; double[][] normals = new double[n][4]; if (n <= 1) { throw new IllegalArgumentException("Can't tube a vertex list of length less than 2"); } double[][] polygon2 = new double[n + 2][]; for (int i = 0; i < n; ++i) { polygon2[i + 1] = polygon[i]; polygon2[0] = Rn.add(null, polygon[0], Rn.subtract(null, polygon[0], polygon[1])); polygon2[n + 1] = Rn.add(null, polygon[n - 1], Rn.subtract(null, polygon[n - 1], polygon[n - 2])); } FrameInfo[] frames = new TubeFactory().makeFrameField(polygon2, FrameFieldType.FRENET, Pn.EUCLIDEAN); for (int i = 0; i < n; ++i) { for (int j = 0; j < 4; ++j) { normals[i][j] = frames[i].frame[4 * j]; } normals[i][3] *= -1; Pn.normalize(normals[i], normals[i], Pn.EUCLIDEAN); } ils.setVertexAttributes( Attribute.NORMALS, StorageModel.DOUBLE_ARRAY.array(4).createReadOnly(normals)); }
public static SceneGraphComponent tubeOneEdge( SceneGraphComponent sgc, double[] ip1, double[] ip2, double rad, double[][] crossSection, int metric) { if (ip1.length < 3 || ip1.length > 4 || ip2.length < 3 || ip2.length > 4) { throw new IllegalArgumentException("Invalid dimension"); } double p1[] = new double[4]; double p2[] = new double[4]; if (ip1.length == 3) Pn.homogenize(p1, ip1); else p1 = ip1; if (ip2.length == 3) Pn.homogenize(p2, ip2); else p2 = ip2; boolean isValid1 = Pn.isValidCoordinate(p1, 3, metric); boolean isValid2 = Pn.isValidCoordinate(p2, 3, metric); if (!isValid1 && !isValid2) return new SceneGraphComponent(); if (!isValid1) Rn.linearCombination(p1, .99, p1, .01, p2); // (p1, p1, p2, .999, metric); else if (!isValid2) Rn.linearCombination(p2, .99, p2, .01, p1); // (p2, p2, p1, .999, metric); Pn.normalize(p1, p1, metric); Pn.normalize(p2, p2, metric); if ((debug & 2) != 0) theLogger.log(Level.FINE, "p1 is " + Rn.toString(p1)); if ((debug & 2) != 0) theLogger.log(Level.FINE, "p2 is " + Rn.toString(p2)); double[] polarPlane = Pn.polarizePoint(null, p1, metric); if ((debug & 2) != 0) theLogger.log(Level.FINE, "Polar plane is " + Rn.toString(polarPlane)); double[] tangent = P3.lineIntersectPlane(null, p1, p2, polarPlane); double[] diff = Rn.subtract(null, p2, p1); if (Rn.innerProduct(diff, tangent) < 0.0) Rn.times(tangent, -1.0, tangent); Pn.setToLength(tangent, tangent, 1.0, metric); double[] normal = Pn.polarizePlane(null, P3.planeFromPoints(null, p1, tangent, e1), metric); double[] binormal = Pn.polarizePlane(null, P3.planeFromPoints(null, p1, tangent, normal), metric); Pn.setToLength(normal, normal, 1.0, metric); Pn.setToLength(binormal, binormal, 1.0, metric); double[] frame = new double[16]; // for reasons unknown/murky, to get a RH.C.S. the vectors have to be assembled as follows in // the matrix System.arraycopy(binormal, 0, frame, 0, 4); System.arraycopy(normal, 0, frame, 4, 4); System.arraycopy(tangent, 0, frame, 8, 4); System.arraycopy(p1, 0, frame, 12, 4); // make sure the transformation is orientation-preserving // NOTE: If there appear shading problems on tubes, un-comment this code // if (Rn.determinant(frame) < 0) { // System.arraycopy(normal, 0, frame, 0, 4); // System.arraycopy(binormal, 0, frame, 4, 4); // // } if ((debug & 16) != 0) { theLogger.log(Level.FINE, "Frame is " + Rn.matrixToString(frame)); theLogger.log(Level.FINE, "Det is " + Rn.determinant(frame)); } Rn.transpose(frame, frame); double[] scaler = Rn.identityMatrix(4); double dist = Pn.distanceBetween(p1, p2, metric); double coord = dist / 2; if (Double.isNaN(coord)) { LoggingSystem.getLogger(TubeUtility.class).warning("bad coord"); return new SceneGraphComponent(); // throw new IllegalStateException("bad coord"); } if (metric == Pn.HYPERBOLIC) coord = Pn.tanh(dist / 2.0); else if (metric == Pn.ELLIPTIC) coord = Math.tan(dist / 2.0); scaler[10] = 2 * coord; double radcoord = rad; if (metric == Pn.HYPERBOLIC) radcoord = Math.sqrt(1 - coord * coord) * Pn.tanh(rad); else if (metric == Pn.ELLIPTIC) radcoord = Math.sqrt(1 + coord * coord) * Math.tan(rad); scaler[0] = scaler[5] = radcoord; if ((debug & 1) != 0) { theLogger.log( Level.FINE, "distance is \t" + dist + " scaler is \t" + coord + " and radius factor is \t" + radcoord); } // LoggingSystem.getLogger().log(Level.FINE,"Frame is "+Rn.matrixToString(frames[0])); // LoggingSystem.getLogger().log(Level.FINE,"Scaler is "+Rn.matrixToString(scaler)); double[] translate = {0, 0, coord, 1}; double[] translateM = P3.makeTranslationMatrix(null, translate, metric); // the matrix net should be a transformation that takes the two input points // to the (dehomogenized) points (0,0,+/-.5,1). double[] net = Rn.times(null, frame, Rn.times(null, translateM, scaler)); if ((debug & 64) != 0) theLogger.log(Level.FINE, "net is \n" + Rn.matrixToString(net)); // double[] inet = Rn.inverse(null, net); // double[] inp1 = Rn.matrixTimesVector(null, inet, p1); // double[] inp2 = Rn.matrixTimesVector(null, inet, p2); // if ((debug & 64) != 0) theLogger.log(Level.FINE,"Image of end points: // "+Rn.toString(Pn.dehomogenize(null,inp1), 6)+" "+Rn.toString(Pn.dehomogenize(null,inp2),6)); if (sgc == null) sgc = new SceneGraphComponent(); sgc.setGeometry(urTube[metric + 1]); if (sgc.getTransformation() == null) sgc.setTransformation(new Transformation()); sgc.getTransformation().setMatrix(net); // LoggingSystem.getLogger().log(Level.FINE,"Matrix is // "+Rn.matrixToString(sgc.getTransformation().getMatrix())); return sgc; }