コード例 #1
0
        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))));
        }
コード例 #2
0
        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)));
        }
コード例 #3
0
    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;
    }
コード例 #4
0
    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);
    }
コード例 #5
0
    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);
        }
    }
コード例 #6
0
    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));
    }
コード例 #7
0
    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);
    }
コード例 #8
0
    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);
    }
コード例 #9
0
    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);
    }