Example #1
0
        /// <summary>
        /// Construct ellipse from two conjugate diameters, and set
        /// Axis0 to the major axis and Axis1 to the minor axis.
        /// The algorithm was constructed from first principles.
        /// Also computes the squared lengths of the major and minor
        /// half axis.
        /// </summary>
        public static __et__ FromConjugateDiameters(__vt__ center, /*# if (d == 3) { */ __vt__ normal, /*# } */ __vt__ a, __vt__ b,
                                                    out double major2, out double minor2)
        {
            var    ab = __vt__.Dot(a, b);
            double a2 = a.LengthSquared, b2 = b.LengthSquared;

            if (ab.IsTiny())
            {
                if (a2 >= b2)
                {
                    major2 = a2; minor2 = b2; return(new __et__(center, /*# if (d == 3) { */ normal, /*# } */ a, b));
                }
                else
                {
                    major2 = b2; minor2 = a2; return(new __et__(center, /*# if (d == 3) { */ normal, /*# } */ b, a));
                }
            }
            else
            {
                var    t = 0.5 * Fun.Atan2(2 * ab, a2 - b2);
                double ct = Fun.Cos(t), st = Fun.Sin(t);
                __vt__ v0 = a * ct + b * st, v1 = b * ct - a * st;
                a2 = v0.LengthSquared; b2 = v1.LengthSquared;
                if (a2 >= b2)
                {
                    major2 = a2; minor2 = b2; return(new __et__(center, /*# if (d == 3) { */ normal, /*# } */ v0, v1));
                }
                else
                {
                    major2 = b2; minor2 = a2; return(new __et__(center, /*# if (d == 3) { */ normal, /*# } */ v1, v0));
                }
            }
        }
Example #2
0
        public static Tup6 <float> Lanczos3f(double x)
        {
            const double a = 1.0 / 3.0;
            double       px = Constant.Pi * x, pxa = px * a;

            if (pxa.IsTiny())
            {
                return(new Tup6 <float>(0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f));
            }
            double p1mx = Constant.Pi - px, p1mxa = p1mx * a;

            if (p1mxa.IsTiny())
            {
                return(new Tup6 <float>(0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f));
            }

            double p1px = Constant.Pi + px, p2px = Constant.PiTimesTwo + px;
            double p2mx = Constant.PiTimesTwo - px, p3mx = Constant.PiTimesThree - px;
            double spx = Fun.Sin(px), spxa = Fun.Sin(pxa);
            double sp1pxa = Fun.Sin(p1px * a), sp2pxa = Fun.Sin(p2px * a);

            return(new Tup6 <float>((float)(spx * sp2pxa / (p2px * p2px * a)),
                                    (float)(-spx * sp1pxa / (p1px * p1px * a)),
                                    (float)((spx / px) * (spxa / pxa)),
                                    (float)((spx / p1mx) * (sp2pxa / p1mxa)),
                                    (float)(-spx * sp1pxa / (p2mx * p2mx * a)),
                                    (float)(spx * spxa / (p3mx * p3mx * a))));
        }
Example #3
0
        /// <summary>
        /// Creates a 2D rotation matrix with the specified angle in radians.
        /// </summary>
        /// <returns>2D Rotation Matrix</returns>
        public static M22d Rotation(double angleInRadians)
        {
            double cos = Fun.Cos(angleInRadians);
            double sin = Fun.Sin(angleInRadians);

            return(new M22d(cos, -sin,
                            sin, cos));
        }
Example #4
0
        /// <summary>
        /// Creates a 2D rotation matrix with the specified angle in radians.
        /// </summary>
        /// <returns>2D Rotation Matrix</returns>
        public static M22f Rotation(float angleInRadians)
        {
            float cos = Fun.Cos(angleInRadians);
            float sin = Fun.Sin(angleInRadians);

            return(new M22f(cos, -sin,
                            sin, cos));
        }
Example #5
0
        /// <summary>
        /// Creates a 2D rotation matrix with the specified angle in radians.
        /// </summary>
        /// <returns>2D Rotation Matrix</returns>
        public static M2__x2t__ Rotation(__ft__ angleInRadians)
        {
            __ft__ cos = Fun.Cos(angleInRadians);
            __ft__ sin = Fun.Sin(angleInRadians);

            return(new M2__x2t__(cos, -sin,
                                 sin, cos));
        }
Example #6
0
        /// <summary>
        /// Creates new rotational matrix for "float value"-radians around Z-Axis.
        /// </summary>
        /// <returns>Rotational matrix.</returns>
        public static M44f RotationZ(float angleRadians)
        {
            float cos = Fun.Cos(angleRadians);
            float sin = Fun.Sin(angleRadians);

            return(new M44f(cos, -sin, 0, 0,
                            sin, cos, 0, 0,
                            0, 0, 1, 0,
                            0, 0, 0, 1));
        }
Example #7
0
        /// <summary>
        /// Creates new rotational matrix for "double value"-radians around Z-Axis.
        /// </summary>
        /// <returns>Rotational matrix.</returns>
        public static M44d RotationZ(double angleRadians)
        {
            double cos = Fun.Cos(angleRadians);
            double sin = Fun.Sin(angleRadians);

            return(new M44d(cos, -sin, 0, 0,
                            sin, cos, 0, 0,
                            0, 0, 1, 0,
                            0, 0, 0, 1));
        }
Example #8
0
        /// <summary>
        /// Creates new rotational matrix for "__ft__ value"-radians around Z-Axis.
        /// </summary>
        /// <returns>Rotational matrix.</returns>
        public static M4__x4t__ RotationZ(__ft__ angleRadians)
        {
            __ft__ cos = Fun.Cos(angleRadians);
            __ft__ sin = Fun.Sin(angleRadians);

            return(new M4__x4t__(cos, -sin, 0, 0,
                                 sin, cos, 0, 0,
                                 0, 0, 1, 0,
                                 0, 0, 0, 1));
        }
Example #9
0
        /// <summary>
        /// Generates normal distributed random variable with given mean and standard deviation.
        /// Uses the Box-Muller Transformation to transform two uniform distributed random variables to one normal distributed value.
        /// NOTE: If multiple normal distributed random values are required, consider using <see cref="RandomGaussian"/>.
        /// </summary>
        public static double Gaussian(this IRandomUniform rnd, double mean = 0.0, double stdDev = 1.0)
        {
            // Box-Muller Transformation
            var u1            = 1.0 - rnd.UniformDouble(); // uniform (0,1] -> log requires > 0
            var u2            = rnd.UniformDouble();       // uniform [0,1)
            var randStdNormal = Fun.Sqrt(-2.0 * Fun.Log(u1)) *
                                Fun.Sin(Constant.PiTimesTwo * u2);

            return(mean + stdDev * randStdNormal);
        }
Example #10
0
        /// <summary>
        /// Perform the supplied action for each of count vectors from the center
        /// of the ellipse to the circumference.
        /// </summary>
        public void ForEachVector(int count, Action <int, __vt__> index_vector_act)
        {
            double d = Constant.PiTimesTwo / count;
            double a = Fun.Sin(d * 0.5).Square() * 2.0, b = Fun.Sin(d); // init trig. recurrence
            double ct = 1.0, st = 0.0;

            index_vector_act(0, Axis0);
            for (int i = 1; i < count; i++)
            {
                double dct = a * ct + b * st, dst = a * st - b * ct;;   // trig. recurrence
                ct -= dct; st -= dst;                                   // cos (t + d), sin (t + d)
                index_vector_act(i, Axis0 * ct + Axis1 * st);
            }
        }
Example #11
0
        /// <summary>
        /// Create from Rodrigues axis-angle vactor
        /// </summary>
        public static __rot3t__ FromAngleAxis(__v3t__ angleAxis)
        {
            __ft__ theta2 = angleAxis.LengthSquared;

            if (theta2 > Constant <__ft__> .PositiveTinyValue)
            {
                var theta     = Fun.Sqrt(theta2);
                var thetaHalf = theta / 2;
                var k         = Fun.Sin(thetaHalf) / theta;
                return(new __rot3t__(Fun.Cos(thetaHalf), k * angleAxis));
            }
            else
            {
                return(new __rot3t__(1, 0, 0, 0));
            }
        }
Example #12
0
        /// <summary>
        /// Return an IEnumerable of points on the circle's circumference, optionally repeating the first point as the last.
        /// </summary>
        /// <param name="tesselation">number of distinct points to generate. the actual number of points returned depends on the <para>duplicateClosePoint</para> parameter. must be 3 or larger.</param>
        /// <param name="duplicateClosePoint">if true, the first point is repeated as the last</param>
        /// <returns>IEnumerable of points on the circle's circumference. if diplicateClosePoint is true, <para>tesselation</para>+1 points are returned.</returns>
        public IEnumerable <V3d> Points(int tesselation, bool duplicateClosePoint = false)
        {
            if (tesselation < 3)
            {
                throw new ArgumentOutOfRangeException("tesselation", "tesselation must be at least 3.");
            }

            var off = 0;

            if (duplicateClosePoint)
            {
                off = 1;
            }
            for (int i = 0; i < tesselation + off; i++)
            {
                var angle = ((double)i) / tesselation * Constant.PiTimesTwo;
                yield return(Center + AxisU * Fun.Cos(angle) + AxisV * Fun.Sin(angle));
            }
        }
Example #13
0
 public __vt__ GetPoint(double alpha)
 {
     return(Center + Axis0 * Fun.Cos(alpha) + Axis1 * Fun.Sin(alpha));
 }
Example #14
0
 public __vt__ GetVector(double alpha)
 {
     return(Axis0 * Fun.Cos(alpha) + Axis1 * Fun.Sin(alpha));
 }
Example #15
0
        private static void FastHartleyTransformRaw(
            this double[] v, long start, long size)
        {
            if (size < 2)
            {
                return;
            }

            /* ---------------------------------------------------------------
            *       The transforming part of the function.  It assumes that all
            *   indices are already bit-reversed.  For successive evaluation
            *   of the trigonometric functions the following recurrence is
            *   used:
            *
            *               a = 2 sin(square(d/2))
            *               b  = sin d
            *
            *               cos(t + d) = cos t - [ a * cos t + b sin t ]
            *               sin(t + d) = sin t - [ a * sin t - b cos t ]
            *
            *       The algorithm is based on the following recursion:
            *
            *               H[f] = Heven[f]
            + cos(2 PI f / n) Hodd[f]
            + sin(2 PI f / n) Hodd[n-f]	f in [0, n-1]
            +
            +               Heven[n/2 + g] = Heven[g]
            +               Hodd [n/2 + g] = Hodd [g]		g in [0, n/2-1]
            +  --------------------------------------------------------------- */
            long end = start + size;

            for (long i = start; i < end; i += 2)
            {
                double h0 = v[i], h1 = v[i + 1];
                v[i] = h0 + h1; v[i + 1] = h0 - h1;     // f = 0, PI
            }
            if (size < 4)
            {
                return;
            }

            for (long i = start; i < end; i += 4)
            {
                double h0 = v[i], h2 = v[i + 2];
                v[i] = h0 + h2; v[i + 2] = h0 - h2;     // f = 0, PI
                double h1 = v[i + 1], h3 = v[i + 3];
                v[i + 1] = h1 + h3; v[i + 3] = h1 - h3; // f = PI/2, 3 * PI/2
            }
            if (size < 8)
            {
                return;
            }

            for (long i = start; i < end; i += 8)
            {
                double h0 = v[i], h4 = v[i + 4];
                v[i] = h0 + h4; v[i + 4] = h0 - h4;     // f = 0, PI
                double one = Constant.Sqrt2Half * (v[i + 5] + v[i + 7]);
                double two = Constant.Sqrt2Half * (v[i + 7] - v[i + 5]);
                double h1 = v[i + 1], h3 = v[i + 3];
                v[i + 1] = h1 + one; v[i + 5] = h1 - one;
                v[i + 3] = h3 - two; v[i + 7] = h3 + two;
                double h2 = v[i + 2], h6 = v[i + 6];
                v[i + 2] = h2 + h6; v[i + 6] = h2 - h6; // f = PI/2, 3 * PI/2
            }
            if (size < 16)
            {
                return;
            }

            var sTable = new double[size / 4];
            var cTable = new double[size / 4];

            for (long len = 8, lenDiv2 = 4, lenMul2 = 16;
                 len < size;
                 lenDiv2 = len, len = lenMul2, lenMul2 = 2 * len)
            {
                double d = Constant.PiTimesTwo / lenMul2;
                double a = Fun.Sin(d * 0.5).Square() * 2.0;  // init trig. recurrence
                double b = Fun.Sin(d);
                double ct = 1.0, st = 0.0;

                for (long f = 1; f < lenDiv2; f++)                       // all freqs in the first quadrant
                {
                    double dct = a * ct + b * st, dst = a * st - b * ct; // trig. rec
                    ct       -= dct; st -= dst;                          // cos (t + d), sin (t + d)
                    cTable[f] = ct; sTable[f] = st;
                }

                for (long i0 = start; i0 < end; i0 += lenMul2)
                {
                    long   i4 = i0 + len;
                    double h0 = v[i0], h4 = v[i4];
                    v[i0] = h0 + h4; v[i4] = h0 - h4;   // f = 0, PI

                    for (long f = 1; f < lenDiv2; f++)  // all freqs in the first quadrant
                    {
                        long   i1 = i0 + f, i3 = i0 + len - f;
                        long   i5 = i1 + len, i7 = i3 + len;
                        double one = cTable[f] * v[i5] + sTable[f] * v[i7];
                        double two = cTable[f] * v[i7] - sTable[f] * v[i5];
                        double h1 = v[i1], h3 = v[i3];
                        v[i1] = h1 + one; v[i5] = h1 - one; // all four quadrants
                        v[i3] = h3 - two; v[i7] = h3 + two; //
                    }

                    long   i2 = i0 + lenDiv2, i6 = i4 + lenDiv2;
                    double h2 = v[i2], h6 = v[i6];
                    v[i2] = h2 + h6; v[i6] = h2 - h6;       // f = PI/2, 3 * PI/2
                }
            }
        }