Example #1
0
 public override Scientrace.VectorTransform getGridTransform(UnitVector nz)
 {
     //construction on request
     if (this.gridtrf == null) {
     Scientrace.Vector refvec;
     //vector has to differ at least 1% from the orthogonal orientation.
     if (Math.Abs(directionlength.toUnitVector().dotProduct(nz))<0.99) {
         refvec = nz;
         } else {
         refvec = (nz.rotateAboutX(Math.PI/2).rotateAboutY(Math.PI/2)).tryToUnitVector();
         if (Math.Abs(directionlength.toUnitVector().dotProduct(nz))<0.99) {
             throw new Exception("WARNING: CrossProducts cannot produce orthogonal lines over two parallel " +
             "vectors, two vectors that are almost parallel will give a large significance error. FIX DIDN'T WORK, please contact the Scientrace developer.");
             }
         }
     Scientrace.NonzeroVector u, v;
     u = refvec.crossProduct(directionlength).tryToUnitVector()*this.radius;
     v = u.crossProduct(directionlength).tryToUnitVector()*this.radius;
     this.gridtrf = new Scientrace.VectorTransform(u,v,this.directionlength);
     }
     return this.gridtrf;
 }
Example #2
0
 public Scientrace.VectorTransform getTransform()
 {
     //construction on request
     if (this.trf == null) {
     this.trf = new Scientrace.VectorTransform(this.u, this.v);
     }
     return this.trf;
 }
 public virtual VectorTransform getTransform()
 {
     //construction on request
     if (this.trf == null) {
     this.trf = this.createNewTransform();
     }
     return this.trf;
 }
        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);
            }
        }