public abstract class GeometricObject { public abstract int getDimension (); public abstract void translate (double[] translation); public abstract void rotate (double[][] matrix); public abstract double[] getCenter (); public static final int dFrom2Vectors (double[] v0, double[] v1) { return (v0 == null || v1 == null) ? 0 : (v0 . length < v1 . length) ? v0 . length : v1 .length; } public static double[] cloneVector (double[] v) { if (v == null) return null; double[] clone = new double [v . length]; for (int i = v . length; --i >= 0 ;) clone [i] = v [i]; return clone; } public void rotate (double[] fromV, double[] toV) { int d = dFrom2Vectors (fromV, toV); if (d < 2 || d > 3) return; // for now double cosTheta = dotProduct (fromV, toV) / Math.sqrt (dotProduct (fromV, fromV) * dotProduct (toV, toV)); double temp = 1 - cosTheta * cosTheta; double sinTheta = (temp > 0.0) ? Math . sqrt (temp) : 0.0; double m_matrix[][] = new double [d][d]; if (d == 2) { m_matrix [0][0] = m_matrix [1][1] = cosTheta; m_matrix [0][1] = (fromV [0] * toV [1] < fromV [1] * toV [1]) ? sinTheta : -sinTheta; m_matrix [1][0] = -m_matrix [0][1]; } else if (d == 3) { double[] V2 = {fromV [1] * toV [2] - fromV [2] * toV [1], fromV [2] * toV [0] - fromV [0] * toV [2], fromV [0] * toV [1] - fromV [1] * toV [0]}; double oneOverLen = 1.0 / Math . sqrt (dotProduct (V2, V2)); V2 [0] *= oneOverLen; V2 [1] *= oneOverLen; V2 [2] *= oneOverLen; double kos = 1 - cosTheta; m_matrix [0][0] = kos * V2 [0] * V2 [0] + cosTheta; m_matrix [1][1] = kos * V2 [1] * V2 [1] + cosTheta; m_matrix [2][2] = kos * V2 [2] * V2 [2] + cosTheta; m_matrix [0][1] = kos * V2 [0] * V2 [1] - sinTheta * V2 [2]; m_matrix [1][0] = kos * V2 [0] * V2 [1] + sinTheta * V2 [2]; m_matrix [0][2] = kos * V2 [0] * V2 [2] + sinTheta * V2 [1]; m_matrix [2][0] = kos * V2 [0] * V2 [2] - sinTheta * V2 [1]; m_matrix [1][2] = kos * V2 [1] * V2 [2] - sinTheta * V2 [0]; m_matrix [2][1] = kos * V2 [1] * V2 [2] + sinTheta * V2 [0]; } rotate (m_matrix); } public static double dotProduct (double[] v0, double[] v1) { double m_sum = 0.0; for (int i = dFrom2Vectors(v0,v1); --i >= 0;) m_sum += v0[i] * v1[i]; return m_sum; } public static void matrixVectorMultiply (double[][] matrix, double[] sourceVector, double[] destVector) { int m_numRows = destVector . length; int m_numCols = sourceVector . length; for (int row = m_numRows; --row >= 0 ;) { double sum = 0.0; for (int col = m_numCols; --col >= 0 ;) sum += matrix [row][col] * sourceVector [col]; destVector [row] = sum; } } public static final double[] intersectionWithImagePlane (double[] point0, double[] point1, int planeD) { if (planeD <= 0 || point0 [planeD] == point1 [planeD]) return null; double[] m_result = new double [planeD]; double m_factor = 1.0 / (point0 [planeD] - point1 [planeD]); for (int i = planeD; --i >= 0 ;) m_result [i] = m_factor * (point0 [planeD] * point1 [i] - point1 [planeD] * point0 [i] ); return m_result; } }