public static Complex Cos(Complex value) { float a = value.m_real; float b = value.m_imaginary; return(new Complex(Mathf.Cos(a) * HyperbolicMath.Cosh(b), -(Mathf.Sin(a) * HyperbolicMath.Sinh(b)))); }
public static Complex Cosh(Complex value) /* Hyperbolic cos */ { float a = value.m_real; float b = value.m_imaginary; return(new Complex(HyperbolicMath.Cosh(a) * Mathf.Cos(b), HyperbolicMath.Sinh(a) * Mathf.Sin(b))); }
public void ComputeRadius(Node parentNode) { //bottom up algorithm. (From leaf to root) //With given leaf size, calculate parent hemsphere size and recursively compute upper level hemsphere size if (parentNode.nodeNumDecendents == 0) { parentNode.nodeHemsphereRadius = leafRadius; return; } else { float parentHemsphereArea = 0.0f; //Hp = sum of pi*r^2 foreach (Node child in parentNode.nodeChildren) { ComputeRadius(child); //recursive bottom up call //Euclidean Space Case for understnding: //parentHemsphereArea += Mathf.Pow(child.nodeHemsphereRadius, 2); //Hyperbolic Space Case: //H3Math.TWO_PI * (H3Math.cosh(r / K) - 1.0); //parentHemsphereArea += (float)(Math.PI * 2 * (Math.Cosh(child.nodeHemsphereRadius / 2) - 1)); parentHemsphereArea += (float)(Math.Cosh(child.nodeHemsphereRadius) - 1); } //Euclidean Space Case: //parentNode.nodeHemsphereRadius = Mathf.Sqrt(parentHemsphereArea); //Hyperbolic Space Case: //K * H3Math.asinh(Math.sqrt(area / (H3Math.TWO_PI * K * K))); //parentNode.nodeHemsphereRadius = (float)HyperbolicMath.ASinh(Math.Sqrt(parentHemsphereArea / (Math.PI * 2 * 4))) * 2; parentNode.nodeHemsphereRadius = (float)HyperbolicMath.ASinh(Math.Sqrt(parentHemsphereArea)); } return; }
public static Vector3 projectAndGetVect3FromHypToEuc(Point4d p) { Vector3 temp = projectAndGetVect3(p); temp.x = HyperbolicMath.euclideanDistance(temp.x); temp.y = HyperbolicMath.euclideanDistance(temp.y); temp.z = HyperbolicMath.euclideanDistance(temp.z); return(temp); }
public void ComputeCoordinatesSubtree(Matrix4d parentTransform, Node parentNode) { if (parentNode.nodeNumDecendents == 0) { return; } float parentRadiusE = HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius); float lastPhi = 0.0f; Matrix4d rotPhi = HyperbolicTransformation.I4; Point4d childCenterAbsolute = new Point4d(); Point4d childPoleAbsolute = new Point4d(); foreach (Node child in parentNode.nodeChildren) { float childRadiusE = HyperbolicMath.euclideanDistance(child.nodeHemsphereRadius); float childPhi = child.nodeHemspherePhi; if (!(Mathf.Abs(childPhi - lastPhi) < EPSILON)) { lastPhi = childPhi; rotPhi = HyperbolicTransformation.buildZRotation(childPhi); } Matrix4d rot = HyperbolicTransformation.buildXRotation(child.nodeHemsphereTheta); rot = rot * rotPhi; childCenterAbsolute.set(parentRadiusE, 0.0f, 0.0f, 1.0f); rot.transform(childCenterAbsolute); float childPoleE = HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius + child.nodeHemsphereRadius); childPoleAbsolute.set(childPoleE, 0.0f, 0.0f, 1.0f); rot.transform(childPoleAbsolute); parentTransform.transform(childCenterAbsolute); parentTransform.transform(childPoleAbsolute); child.nodeEuclideanPosition = childCenterAbsolute; //graph.setNodeLayoutCoordinates(child, childCenterAbsolute); Matrix4d childTransform = HyperbolicTransformation.buildCanonicalOrientation(childCenterAbsolute, childPoleAbsolute); ComputeCoordinatesSubtree(childTransform, child); } }
private static Point4d findPivotPoint(Point4d a4, Point4d b4) { Vector3 a = new Vector3(); Vector3 b = new Vector3(); a = Point4d.projectAndGetVect3(a4); b = Point4d.projectAndGetVect3(b4); Vector3 a_minus_b = new Vector3(a.x - b.x, a.y - b.y, a.z - b.z); float p = HyperbolicMath.dotProduct(a, a_minus_b); float q = HyperbolicMath.dotProduct(b, a_minus_b); float r = HyperbolicMath.dotProduct(a_minus_b, a_minus_b); return(new Point4d(p * b.x - q * a.x, p * b.y - q * a.y, p * b.z - q * a.z, r)); }
public static Matrix4d buildCanonicalOrientation(Point4d a, Point4d b) { /* local scratch variables; will be transformed */ Point4d pa = new Point4d(a.x, a.y, a.z, a.w); Point4d pb = new Point4d(b.x, b.y, b.z, b.w); Point4d pivot = findPivotPoint(pa, pb); Matrix4d retval = buildTranslation(ORIGIN4, pivot); Matrix4d t1 = buildTranslation(pivot, ORIGIN4); t1.transform(pa); t1.transform(pb); retval *= buildTranslation(ORIGIN4, pa); Matrix4d t2 = buildTranslation(pa, ORIGIN4); t2.transform(pa); t2.transform(pb); /* calculate spherical coordinates (rho, phi, theta) of pb */ // Projection to affine coordinates is necessary so that we can // directly reference the x, y, and z components in the following // calculations. pb.project(); float rho = HyperbolicMath.vectorLength(pb); float phi = Mathf.Acos(pb.x / rho); float theta = Mathf.Atan2(pb.z, pb.y); if (phi == 0.0f) { /* rotate line to achieve alignment on positive x-axis */ retval *= buildXRotation(theta); retval *= buildZRotation(phi); } return(retval); }
public static Matrix4d buildTranslation(Point4d source, Point4d dest) { float aa_h = HyperbolicMath.MinkowskiInnerProduct(source, source); float bb_h = HyperbolicMath.MinkowskiInnerProduct(dest, dest); float ab_h = HyperbolicMath.MinkowskiInnerProduct(source, dest); float sourceScale = Mathf.Sqrt(bb_h * ab_h); float destScale = Mathf.Sqrt(aa_h * ab_h); Point4d midpoint = new Point4d(); midpoint.x = sourceScale * source.x + destScale * dest.x; midpoint.y = sourceScale * source.y + destScale * dest.y; midpoint.z = sourceScale * source.z + destScale * dest.z; midpoint.w = sourceScale * source.w + destScale * dest.w; Matrix4d r_a = buildReflection(source); Matrix4d r_m = buildReflection(midpoint); r_m *= r_a; return(r_m); }
public void ComputeCoordinatesEuclidean(Node parentNode) { /* * if (parentNode.nodeNumDecendents == 0) * { * return; * } * else * { * Matrix4x4 translationMatrix = Matrix4x4.Translate(new Vector3(HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius) + parentNode.nodeEuclideanPosition.x, parentNode.nodeEuclideanPosition.y, parentNode.nodeEuclideanPosition.z)); * foreach (Node child in parentNode.nodeChildren) * { * Vector3 childCoord = Point4d.projectAndGetVect3(child.nodeRelativeHyperbolicProjectionPosition); * childCoord = translationMatrix.MultiplyPoint(childCoord); * * Quaternion rotation = Quaternion.Euler(child.nodeHemsphereTheta, 0.0f, child.nodeHemspherePhi); * // Set the translation, rotation and scale parameters. * //Matrix4x4 m = Matrix4x4.TRS(new Vector3(HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius) + parentNode.nodeEuclideanPosition.x, parentNode.nodeEuclideanPosition.y, parentNode.nodeEuclideanPosition.z), rotation, new Vector3(globalScaler, globalScaler, globalScaler)); * Matrix4x4 m = Matrix4x4.TRS(new Vector3(0.0f, 0.0f, 0.0f), rotation, new Vector3(globalScaler, globalScaler, globalScaler)); * Vector3 tempVect3 = m.MultiplyPoint3x4(childCoord); * child.nodeEuclideanPosition = new Point4d(tempVect3.x, tempVect3.y, tempVect3.z); * ComputeCoordinatesEuclidean(child); * } * } */ if (parentNode.nodeNumDecendents == 0) { return; } else { //Matrix4d rotationOfCoordinate = HyperbolicTransformation.buildCanonicalOrientationEuclidean(HyperbolicTransformation.ORIGIN4, parentNode.nodeEuclideanPosition); float parentPhi = Point4d.getPhiByPoint(parentNode.nodeEuclideanPosition); float parentTheta = Point4d.getThetaByPoint(parentNode.nodeEuclideanPosition); Debug.Log(parentNode.nodeEuclideanPosition.x + " " + parentNode.nodeEuclideanPosition.y + " " + parentNode.nodeEuclideanPosition.z); foreach (Node child in parentNode.nodeChildren) { Vector3 childCoord = Point4d.projectAndGetVect3(child.nodeRelativeHyperbolicProjectionPosition); //Matrix4x4 scaler = Matrix4x4.Scale(new Vector3(globalScaler, globalScaler, globalScaler)); //scaler.MultiplyPoint3x4(childCoord); //Debug.Log(rotationOfCoordinate.matrix4d); //rotationOfCoordinate.matrix4d.MultiplyPoint3x4(childCoord); //child.nodeHemsphereTheta / Mathf.PI * 180, 0.0f, child.nodeHemspherePhi / Mathf.PI * 180 //Quaternion rotation = Quaternion.Euler(parentNode.nodeHemsphereTheta / Mathf.PI * 180, parentNode.nodeHemspherePhi / Mathf.PI * 180, 0.0f); //Quaternion rotation = Quaternion.Euler(child.nodeHemsphereTheta + parentTheta, 0.0f, child.nodeHemspherePhi + parentPhi); //Quaternion rotation = Quaternion.Euler(parentPhi / Mathf.PI * 180, 0.0f, parentTheta / Mathf.PI * 180); float xAngRot; float yAngRot; if (parentNode.nodeParent == null) { xAngRot = Point4d.getRotAngleX(parentNode.nodeEuclideanPosition); yAngRot = Point4d.getRotAngleY(parentNode.nodeEuclideanPosition); } else { xAngRot = -Point4d.getRotAngleX(parentNode.nodeEuclideanPosition - parentNode.nodeParent.nodeEuclideanPosition); yAngRot = Point4d.getRotAngleY(parentNode.nodeEuclideanPosition - parentNode.nodeParent.nodeEuclideanPosition); } //xAngRot += Point4d.getRotAngleX(new Point4d(childCoord.x, childCoord.y, childCoord.z)); //yAngRot += Point4d.getRotAngleY(new Point4d(childCoord.x, childCoord.y, childCoord.z)); Quaternion rotation = Quaternion.Euler(xAngRot / Mathf.PI * 180, yAngRot / Mathf.PI * 180, 0.0f); //Matrix4x4 rotationMatrix = Matrix4x4.Rotate(rotation); //childCoord = rotationMatrix.MultiplyPoint(childCoord); //rotation = Quaternion.Euler(0.0f, 0.0f, 0.0f); Matrix4x4 m = Matrix4x4.TRS(new Vector3(HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius) + parentNode.nodeEuclideanPosition.x, parentNode.nodeEuclideanPosition.y, parentNode.nodeEuclideanPosition.z), rotation, new Vector3(globalScaler, globalScaler, globalScaler)); //Matrix4x4 m = Matrix4x4.TRS(new Vector3(HyperbolicMath.euclideanDistance(parentNode.nodeHemsphereRadius) + parentNode.nodeEuclideanPosition.x, parentNode.nodeEuclideanPosition.y, parentNode.nodeEuclideanPosition.z), rotation, new Vector3(globalScaler, globalScaler, globalScaler)); childCoord = m.MultiplyPoint(childCoord); //rotation = Quaternion.Euler(parentTheta, 0.0f, parentPhi); Debug.Log(parentNode.nodeName + " " + child.nodeName + " " + (parentTheta / Mathf.PI * 180) + " " + (parentPhi / Mathf.PI * 180)); //m = Matrix4x4.Rotate(rotation); //childCoord = m.MultiplyPoint3x4(childCoord); child.nodeEuclideanPosition = new Point4d(childCoord.x, childCoord.y, childCoord.z); ComputeCoordinatesEuclidean(child); } } //ComputeCoordinatesEuclideanTest(parentNode, 0.0f, 0.0f); }