Beispiel #1
0
 public void testDotProductResults()
 {
     Random r = new Random();
     for (int i = 0; i<1000; i++) {
     Scientrace.Vector a,b;
         a = new Scientrace.Vector(r.NextDouble()*100,r.NextDouble()*100,r.NextDouble()*100);
         b = new Scientrace.Vector(r.NextDouble()*100,r.NextDouble()*100,r.NextDouble()*100);
         Assert.LessOrEqual(Math.Abs(a.tryToUnitVector().dotProduct(b.tryToUnitVector())), 1);
     }
 }
Beispiel #2
0
        public void testDotProductResults()
        {
            Random r = new Random();

            for (int i = 0; i < 1000; i++)
            {
                Scientrace.Vector a, b;
                a = new Scientrace.Vector(r.NextDouble() * 100, r.NextDouble() * 100, r.NextDouble() * 100);
                b = new Scientrace.Vector(r.NextDouble() * 100, r.NextDouble() * 100, r.NextDouble() * 100);
                Assert.LessOrEqual(Math.Abs(a.tryToUnitVector().dotProduct(b.tryToUnitVector())), 1);
            }
        }
        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
            }
        }
Beispiel #4
0
 public string x3dRotationTransform(Scientrace.Vector orivec)
 {
     //the Circle2D objects will normally be drawn in the x,y plane (perpendicular to 0,0,1) so it has to
     //rotated out of that plane as follows.
     Scientrace.UnitVector oriunivec = orivec.tryToUnitVector();
     Scientrace.UnitVector uxv       = (this.u.crossProduct(this.v).tryToUnitVector());
     if (uxv == oriunivec)
     {
         return("<Transform rotation='0 0 0 0'>");
         //	throw new ArithmeticException("Plane vectors uxv ("+uxv.trico()+") & oriunivec ("+oriunivec.trico()+") are equal");
     }
     try {
         Scientrace.UnitVector rotaxis = (oriunivec).crossProduct(uxv).tryToUnitVector();
         return("<Transform rotation='" + rotaxis.trico() + " " + (oriunivec.angleWith(rotaxis)).ToString() + "'>");
     } catch     // possible error: zerovector after cross product (rounding error at first comparison), return zero rotation tag.
     { return("<Transform rotation='0 0 0 0'>"); }
 }
Beispiel #5
0
 public double angleOnSurface(Scientrace.Vector aVector)
 {
     return(this.angleOnSurface(aVector.tryToUnitVector()));
 }
Beispiel #6
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
Beispiel #7
0
        /* Classes supporthing the creation of the lightsource */
        public Scientrace.LightSource setRandomCylinderLightFromXData(XElement xlight,
                                                                      Scientrace.Object3dEnvironment env)
        {
            //Reading LightSource parameters from XML-element

            /* "RandomCylinder"
             * d class.radius, d distance, i beamcount, i maxinteractions, d minintensity
             * str spectrum, vec location, vec direction */
            double radius = this.X.getXDouble(xlight.Attribute("Radius"));

            if (radius <= 0)
            {
                throw new ArgumentOutOfRangeException("Radius " + radius + " out of range");
            }
            double distance  = this.X.getXDouble(xlight.Attribute("Distance"), 0);
            int    beamcount = this.X.getXInt(xlight.Attribute("RayCount"), this.X.getXInt(xlight.Attribute("BeamCount")));
            //int maxinteractions = this.X.getXInt(xlight.Attribute("MaxInteractions"), 8); //default value max_interactions -> 8
            double minintensity = this.X.getXDouble(xlight.Attribute("MinIntensity"), 0.01);             //default minimum intensity for tracing set to 1%

            Scientrace.Vector   light_direction = this.X.getXVector(xlight.Element("Direction"));
            Scientrace.Location centerloc       = this.X.getXVector(xlight.Element("Location")).toLocation();
            Scientrace.Location locoffset       = (light_direction.negative() * distance).toLocation();     //distance cm above surface
            Scientrace.Location loc             = locoffset + centerloc;
            XMLSpectrumParser   xsp             = new XMLSpectrumParser();

            Scientrace.LightSpectrum spectrum = xsp.parseLightSpectrum(xlight.Element("Spectrum"));

            Scientrace.LightSource retlight = new Scientrace.RandomCircleLightSource(env,
                                                                                     loc, light_direction.tryToUnitVector(),
                                                                                     new Scientrace.Plane(new Scientrace.Location(0, 0, 0), new Scientrace.NonzeroVector(1, 0, 0), new Scientrace.NonzeroVector(0, 0, 1)),
                                                                                     radius, beamcount, spectrum);
            //retlight.max_interactions = maxinteractions;
            retlight.minimum_intensity_fraction = minintensity;
            return(retlight);
        }
Beispiel #8
0
 public double angleWith(Scientrace.Vector v)
 {
     return(Math.Acos(this.roundForInverseAngleFunction(this.tryToUnitVector().dotProduct(v.tryToUnitVector()))));
 }