예제 #1
0
 public void TestNormalizing()
 {
     Scientrace.NonzeroVector v1 = new Scientrace.NonzeroVector(1, 2, 3);
     Scientrace.NonzeroVector v2 = v1.copy().tryToNonzeroVector();
     v2.normalize();
     Assert.AreEqual(v1.normalized(), v2);
 }
예제 #2
0
        public string getX3DRotationTag(Scientrace.NonzeroVector fromVector, Scientrace.NonzeroVector toVector)
        {
            Scientrace.Vector r     = fromVector.crossProduct(toVector);
            double            angle =
                Math.Acos(toVector.normalized().dotProduct(fromVector.normalized()))         // the angle to be rotated
                * Math.Sign(r.crossProduct(fromVector).dotProduct(toVector));

            try {
                return("<Transform rotation='" + r.tryToUnitVector().trico() + " " + angle + "' >");
            } catch {                  // if fromVector has the same direction as toVector, the crossProduct is a zerovector which cannot be normalized.
                return("<Transform>"); //no transformation, just open so it can be closed afterwards
            }
        }
예제 #3
0
        /// <summary>
        /// Use function below to transform a vector over any angle v. Keep in mind that this
        /// function uses significantly more processingpower than the aboutX,Y,Z functions.
        /// </summary>
        /// <param name="v">
        /// A <see cref="Scientrace.NonzeroVector"/> about which the vector should be rotated
        /// </param>
        /// <param name="radians">
        /// A <see cref="System.Double"/> an angle in radians about which the vetor should be rotated
        /// anticlockwise with the vector V rising towards the viewer.
        /// </param>
        /// <returns>
        /// A <see cref="Vector"/> which is the result of the rotating operation. The original (this)
        /// vector is not modified during this operation.
        /// </returns>
        public Vector rotateAboutVector(Scientrace.NonzeroVector v, double radians)
        {
            NonzeroVector tv1;

            if (Math.Abs(new NonzeroVector(1, 0, 0).normalized().dotProduct(v.normalized())) < 0.9)
            {
                //throw new Exception("A: "+v.trico()+" cross: "+new NonzeroVector(1,0,0).crossProduct(v));
                tv1 = new NonzeroVector(1, 0, 0).crossProduct(v).tryToNonzeroVector().normalized();
            }
            else
            {
                tv1 = new NonzeroVector(0, 1, 0).crossProduct(v).tryToNonzeroVector().normalized();
            }
            NonzeroVector tv2 = v.crossProduct(tv1).tryToNonzeroVector().normalized();
            VectorTransformOrthonormal vtrf = new VectorTransformOrthonormal(tv1, tv2, v);
            Vector tvec = vtrf.transform(this);

            tvec = tvec.rotateAboutZ(radians);
            return(vtrf.transformback(tvec));
        }
예제 #4
0
 public void TestNormalizing()
 {
     Scientrace.NonzeroVector v1 = new Scientrace.NonzeroVector(1,2,3);
     Scientrace.NonzeroVector v2 = v1.copy().tryToNonzeroVector();
     v2.normalize();
     Assert.AreEqual(v1.normalized(), v2);
 }
예제 #5
0
        private Scientrace.NonzeroVector calcTriangleHeightVector(ShadowObject3d sho3d)
        {
            Scientrace.Vector length    = sho3d.getVector("length");
            Scientrace.Vector width     = sho3d.getVector("width");
            Scientrace.Vector heightdir = sho3d.getVector("heightdir");

            double angle = sho3d.getDouble("angle");

            //create a vector orthogonal to length en width in the same binary direction as heightdir.
            Scientrace.UnitVector owl = (width.crossProduct(length) *
                                         Math.Sign(width.crossProduct(length).dotProduct(heightdir))).tryToUnitVector();

            Scientrace.NonzeroVector bdir = (     //calculate the direction of the short side of the prism
                owl * Math.Sin(angle) +
                width.tryToUnitVector() * Math.Cos(angle)
                ).tryToNonzeroVector();
            if ((bdir.length < 0.99999) || (bdir.length > 1.00001))
            {
                throw new ArgumentOutOfRangeException("bdir.length", bdir.length, "!= 1");
            }

            Scientrace.VectorTransform trf = new Scientrace.VectorTransform(
                width.tryToNonzeroVector(), owl.tryToNonzeroVector(), length.tryToNonzeroVector());
            Scientrace.NonzeroVector hdirtrf   = trf.transform(heightdir).tryToNonzeroVector();
            Scientrace.Vector        hprimetrf = new Scientrace.Vector(hdirtrf.x, hdirtrf.y, 0); //eliminate "length" component of heightdir in hprime
            //Console.WriteLine("HPRIMTRF:"+hprimetrf.trico());
            Scientrace.NonzeroVector hprimedir = trf.transformback(hprimetrf).tryToNonzeroVector().normalized();

            /*       ^
             *      /C\
             *     /   \
             *  h'/     \ b
             *   /       \
             *  /B_______A\
             *     width
             * angle = A; beta = B; gamma = C.
             */
            //sine rule: hprimelen / sin A = width.length() / sin C = blen / sin B
            double beta, gamma;

            beta  = Math.Acos(hprimedir.normalized().dotProduct(width.tryToNonzeroVector().normalized()));
            gamma = Math.PI - (angle + beta);
            double hprimelen;
            double sinruleconstant = width.length / Math.Sin(gamma);

            hprimelen = sinruleconstant * Math.Sin(angle);
            Scientrace.NonzeroVector hprime = hprimedir * hprimelen;

            // check: (trf.transform(hprime).x / hdirtrf.x) == (trf.transform(hprime).y / hdirtrf.y)
            double xycoeff = ((trf.transform(hprime).x / hdirtrf.x) / (trf.transform(hprime).y / hdirtrf.y));

            if (Math.Abs(1 - xycoeff) > 0.00001)   //doesn't do anything if .x/.x = NaN, but that's OK for now.
            {
                throw new ArgumentOutOfRangeException("xycoeff", xycoeff, "!=1");
            }

            try {
                Scientrace.NonzeroVector h = ((Math.Abs(hdirtrf.x) > Math.Abs(hdirtrf.y)) ? // Preventing .x or .y denominator == 0 errors.
                                              trf.transformback(hdirtrf * (trf.transform(hprime).x / hdirtrf.x)) :
                                              trf.transformback(hdirtrf * (trf.transform(hprime).y / hdirtrf.y))
                                              ).tryToNonzeroVector();

                return(h);
            } catch (Scientrace.ZeroNonzeroVectorException zne)     {
                Console.WriteLine("ERROR: calculated height for triangularprism has length zero!");
                throw (zne);
            }
        }         //end calcTriangleHeightVector