Example #1
0
        public void Vector2AbsTest()
        {
            Vector2D <float> v1 = new Vector2D <float>(-2.5f, 2.0f);
            Vector2D <float> v3 = Vector2D.Abs(new Vector2D <float>(0.0f, float.NegativeInfinity));
            Vector2D <float> v  = Vector2D.Abs(v1);

            Assert.Equal(2.5f, v.X);
            Assert.Equal(2.0f, v.Y);
            Assert.Equal(0.0f, v3.X);
            Assert.Equal(float.PositiveInfinity, v3.Y);
        }
Example #2
0
        public void Vector2AbsTest()
        {
            Vector2D v1 = new Vector2D(-2.5f, 2.0f);
            Vector2D v3 = Vector2D.Abs(new Vector2D(0.0f, double.NegativeInfinity));
            Vector2D v  = Vector2D.Abs(v1);

            Assert.AreEqual(2.5f, v.X);
            Assert.AreEqual(2.0f, v.Y);
            Assert.AreEqual(0.0f, v3.X);
            Assert.AreEqual(double.PositiveInfinity, v3.Y);
        }
Example #3
0
        /// <summary>
        /// Creates a new rounded rectangle shaped sub-path with varying radii for each corner.
        /// </summary>
        public static void RoundedRectVarying(this Nvg nvg, Rectangle <float> rect, float radTopLeft, float radTopRight, float radBottomRight, float radBottomLeft)
        {
            if (radTopLeft < 0.1f && radTopRight < 0.1f && radBottomRight < 0.1f && radBottomLeft < 0.1f)
            {
                Rect(nvg, rect);
            }
            else
            {
                InstructionQueue queue = nvg.instructionQueue;

                float            factor = 1 - KAPPA90;
                Vector2D <float> half   = Vector2D.Abs(rect.Size) * 0.5f;
                Vector2D <float> rBL    = new(MathF.Min(radBottomLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomLeft, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rBR    = new(MathF.Min(radBottomRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radBottomRight, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rTR    = new(MathF.Min(radTopRight, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopRight, half.Y) * Maths.Sign(rect.Size.Y));
                Vector2D <float> rTL    = new(MathF.Min(radTopLeft, half.X) * Maths.Sign(rect.Size.X), MathF.Min(radTopLeft, half.Y) * Maths.Sign(rect.Size.Y));
                queue.AddMoveTo(new(rect.Origin.X, rect.Origin.Y + rTL.Y));
                queue.AddLineTo(new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X, rect.Origin.Y + rect.Size.Y - rBL.Y * factor),
                    new(rect.Origin.X + rBL.X * factor, rect.Origin.Y + rect.Size.Y),
                    new(rect.Origin.X + rBL.X, rect.Origin.Y + rect.Size.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rect.Size.X - rBR.X, rect.Origin.Y + rect.Size.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rect.Size.X - rBR.X * factor, rect.Origin.Y + rect.Size.Y),
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y * factor),
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rect.Size.Y - rBR.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rect.Size.X, rect.Origin.Y + rTR.Y * factor),
                    new(rect.Origin.X + rect.Size.X - rTR.X * factor, rect.Origin.Y),
                    new(rect.Origin.X + rect.Size.X - rTR.X, rect.Origin.Y)
                    );
                queue.AddLineTo(new(rect.Origin.X + rTL.X, rect.Origin.Y));
                queue.AddBezierTo(
                    new(rect.Origin.X + rTL.X * factor, rect.Origin.Y),
                    new(rect.Origin.X, rect.Origin.Y + rTL.Y * factor),
                    new(rect.Origin.X, rect.Origin.Y + rTL.Y)
                    );
                queue.AddClose();
            }
        }
Example #4
0
        public bool RayCast(out b2RayCastOutput output, b2RayCastInput input)
        {
            float tmin = -float.MaxValue;
            float tmax = float.MaxValue;

            Vector2D p    = input.p1;
            Vector2D d    = input.p2 - input.p1;
            Vector2D absD = Vector2D.Abs(d);

            Vector2D normal = Vector2D.Zero;

            for (int i = 0; i < 2; ++i)
            {
                if (absD[i] < float.Epsilon)
                {
                    if (p[i] < LowerBound[i] || UpperBound[i] < p[i])
                    {
                        output.fraction = tmin;
                        output.Normal   = null;
                        return(false);
                    }
                }
                else
                {
                    float inv_d = 1.0f / d[i];
                    float t1    = (LowerBound[i] - p[i]) * inv_d;
                    float t2    = (UpperBound[i] - p[i]) * inv_d;

                    // Sign of the normal vetor
                    float s = -1.0f;
                    if (t1 > t2)
                    {
                        // Swap t values
                        float tmp = t1;
                        t1 = t2;
                        t2 = t1;
                        s  = 1.0f;
                    }
                    // Push the main up
                    if (t1 > tmin)
                    {
                        normal    = Vector2D.Zero;
                        normal[i] = s;
                        tmin      = t1;
                    }
                    // Pull the max down
                    tmax = System.Math.Min(tmax, t2);

                    if (tmin > tmax)
                    {
                        output.fraction = 0f;
                        output.Normal   = null;
                        return(false);
                    }
                }
            }

            if (tmin < 0.0f || input.maxFraction < tmin)
            {
                output.fraction = 0.0f;
                output.Normal   = null;
                return(false);
            }

            output.fraction = tmin;
            output.Normal   = normal;
            return(true);
        }
Example #5
0
        /// <summary>
        /// This method can be used to test if the construction of the linear affine flux
        /// was correct
        /// </summary>
        /// <returns>if the given nonlinear flux is representable as an affine linear function,
        /// this should return 0 or a very small value</returns>
        public double Test()
        {
            Vector2D X;
            Vector2D n;

            int L = m_Flux.ArgumentOrdering.Length;
            int I = 20 * L;

            Random rand = new Random();

            double[] Uin  = new double[L];
            double[] Uout = new double[L];

            Vector2D o;

            Vector2D[] m1 = new Vector2D[L];
            Vector2D[] m2 = new Vector2D[L];

            double oSc;

            double[] m1Sc = new double[L];
            double[] m2Sc = new double[L];

            double errsum = 0.0;

            for (int i = 0; i < I; i++)
            {
                // populate Arguments with random values
                // -------------------------------------
                X.x = rand.NextDouble() * 10.0 - 5.0;
                X.y = rand.NextDouble() * 10.0 - 5.0;

                for (int l = L - 1; l >= 0; l--)
                {
                    Uin[l]  = rand.NextDouble() * 2.0 - 1.0;
                    Uout[l] = rand.NextDouble() * 2.0 - 1.0;
                }

                n.x = rand.NextDouble() * 2.0 - 1.0;
                n.y = rand.NextDouble() * 2.0 - 1.0;
                n.Normalize();



                // test "BorderEdgeFlux"
                // ---------------------
                {
                    // "nonlinear" version
                    double nbe = m_Flux.BorderEdgeFlux(0.0, X, n, Uin);

                    // linear version
                    this.BorderEdgeFlux(0.0, X, n, m1Sc, out oSc);

                    double lbe = 0.0;
                    lbe += oSc;

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lbe += m1Sc[l] * Uin[l];
                    }

                    nbe    -= lbe; // now, "nbe" should be equal to "lbe"
                    errsum += Math.Abs(nbe);
                }

                // test "Flux"
                // -----------
                {
                    // "nonlinear" version
                    Vector2D nf = m_Flux.Flux(0.0, X, Uin);

                    // linear version
                    this.Flux(0.0, X, m1, out o);

                    Vector2D lf = new Vector2D();
                    lf.Acc(o);

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lf.Acc(m1[l], Uin[l]);
                    }

                    nf.Sub(lf); // now, "nf" should be equal to "lf"
                    errsum += nf.Abs();
                }

                // test "Flux"
                // -----------
                {
                    // "nonlinear" version
                    double nif = m_Flux.InnerEdgeFlux(0.0, X, n, Uin, Uout);

                    // linear version
                    this.InnerEdgeFlux(0.0, X, n, m1Sc, m2Sc, out oSc);

                    double lif = 0.0;
                    lif += oSc;

                    for (int l = L - 1; l >= 0; l--)
                    {
                        lif += m1Sc[l] * Uin[l];
                    }
                    for (int l = L - 1; l >= 0; l--)
                    {
                        lif += m2Sc[l] * Uout[l];
                    }

                    nif    -= lif; // now, "nif" should be equal to "lif"
                    errsum += Math.Abs(nif);
                }
            }

            return(errsum);
        }