Exemplo n.º 1
0
        public override void findBounds(ref double left, ref double bottom, ref double right, ref double top)
        {
            Vector2.pointBounds(p[0], ref left, ref bottom, ref right, ref top);
            Vector2.pointBounds(p[3], ref left, ref bottom, ref right, ref top);
            Vector2 a0 = p[1] - p[0];
            Vector2 a1 = 2 * (p[2] - p[1] - a0);
            Vector2 a2 = p[3] - 3 * p[2] + 3 * p[1] - p[0];

            double[] pars = new double[2];
            int      solutions;

            solutions = EquationSolver.SolveQuadratic(pars, a2.x, a1.x, a0.x);
            for (int i = 0; i < solutions; ++i)
            {
                if (pars[i] > 0 && pars[i] < 1)
                {
                    Vector2.pointBounds(point(pars[i]), ref left, ref bottom, ref right, ref top);
                }
            }
            solutions = EquationSolver.SolveQuadratic(pars, a2.y, a1.y, a0.y);
            for (int i = 0; i < solutions; ++i)
            {
                if (pars[i] > 0 && pars[i] < 1)
                {
                    Vector2.pointBounds(point(pars[i]), ref left, ref bottom, ref right, ref top);
                }
            }
        }
Exemplo n.º 2
0
        public override void findBounds(ref double left, ref double bottom, ref double right, ref double top)
        {
            Vector2.pointBounds(_p0, ref left, ref bottom, ref right, ref top);
            Vector2.pointBounds(_p3, ref left, ref bottom, ref right, ref top);
            //
            Vector2 a0 = _p1 - _p0;
            Vector2 a1 = 2 * (_p2 - _p1 - a0);
            Vector2 a2 = _p3 - 3 * _p2 + 3 * _p1 - _p0;
            //
            EqResult pars      = new EqResult();
            int      solutions = EquationSolver.SolveQuadratic(ref pars, a2.x, a1.x, a0.x);

            for (int i = 0; i < solutions; ++i)
            {
                double par = pars[i];
                if (par > 0 && par < 1)
                {
                    Vector2.pointBounds(point(par), ref left, ref bottom, ref right, ref top);
                }
            }

            pars      = new EqResult();
            solutions = EquationSolver.SolveQuadratic(ref pars, a2.y, a1.y, a0.y);

            for (int i = 0; i < solutions; ++i)
            {
                double par = pars[i];
                if (par > 0 && par < 1)
                {
                    Vector2.pointBounds(point(par), ref left, ref bottom, ref right, ref top);
                }
            }
        }
Exemplo n.º 3
0
        public override SignedDistance signedDistance(Vector2 origin, out double param)
        {
            Vector2 qa = _p0 - origin;
            Vector2 ab = _p1 - _p0;
            Vector2 br = _p0 + _p2 - _p1 - _p1;//

            double a = Vector2.dotProduct(br, br);
            double b = 3 * Vector2.dotProduct(ab, br);
            double c = 2 * Vector2.dotProduct(ab, ab) + Vector2.dotProduct(qa, br);
            double d = Vector2.dotProduct(qa, ab);

            EqResult t = new EqResult();

            int solutions = EquationSolver.SolveCubic(ref t, a, b, c, d);

            double minDistance = nonZeroSign(Vector2.crossProduct(ab, qa)) * qa.Length(); // distance from A

            param = -Vector2.dotProduct(qa, ab) / Vector2.dotProduct(ab, ab);
            {
                double distance = nonZeroSign(
                    Vector2.crossProduct(_p2 - _p1, _p2 - origin)) * (_p2 - origin).Length(); // distance from B
                if (Math.Abs(distance) < Math.Abs(minDistance))
                {
                    minDistance = distance;
                    param       = Vector2.dotProduct(origin - _p1, _p2 - _p1) / Vector2.dotProduct(_p2 - _p1, _p2 - _p1);
                }
            }

            //possible solution -1,0,1,2
            for (int i = 0; i < solutions; ++i)
            {
                double ti = t[i];

                if (ti > 0 && ti < 1)
                {
                    Vector2 endpoint = _p0 + 2 * ti * ab + ti * ti * br;
                    double  distance = nonZeroSign(
                        Vector2.crossProduct(_p2 - _p0, endpoint - origin)) * (endpoint - origin).Length();
                    if (Math.Abs(distance) <= Math.Abs(minDistance))
                    {
                        minDistance = distance;
                        param       = ti;
                    }
                }
            }

            if (param >= 0 && param <= 1)
            {
                return(new SignedDistance(minDistance, 0));
            }
            if (param < .5)
            {
                return(new SignedDistance(minDistance, Math.Abs(Vector2.dotProduct(ab.normalize(), qa.normalize()))));
            }
            else
            {
                return(new SignedDistance(minDistance, Math.Abs(Vector2.dotProduct((_p2 - _p1).normalize(), (_p2 - origin).normalize()))));
            }
        }
Exemplo n.º 4
0
        public override SignedDistance signedDistance(Vector2 origin, out double param)
        {
            Vector2 qa = p[0] - origin;
            Vector2 ab = p[1] - p[0];
            Vector2 br = p[0] + p[2] - p[1] - p[1];
            double  a  = Vector2.dotProduct(br, br);
            double  b  = 3 * Vector2.dotProduct(ab, br);
            double  c  = 2 * Vector2.dotProduct(ab, ab) + Vector2.dotProduct(qa, br);
            double  d  = Vector2.dotProduct(qa, ab);

            double[] t         = new double[3];
            int      solutions = EquationSolver.SolveCubic(t, a, b, c, d);

            double minDistance = nonZeroSign(Vector2.crossProduct(ab, qa)) * qa.Length(); // distance from A

            param = -Vector2.dotProduct(qa, ab) / Vector2.dotProduct(ab, ab);
            {
                double distance = nonZeroSign(
                    Vector2.crossProduct(p[2] - p[1], p[2] - origin)) * (p[2] - origin).Length(); // distance from B
                if (Math.Abs(distance) < Math.Abs(minDistance))
                {
                    minDistance = distance;
                    param       = Vector2.dotProduct(origin - p[1], p[2] - p[1]) / Vector2.dotProduct(p[2] - p[1], p[2] - p[1]);
                }
            }
            for (int i = 0; i < solutions; ++i)
            {
                if (t[i] > 0 && t[i] < 1)
                {
                    Vector2 endpoint = p[0] + 2 * t[i] * ab + t[i] * t[i] * br;
                    double  distance = nonZeroSign(
                        Vector2.crossProduct(p[2] - p[0], endpoint - origin)) * (endpoint - origin).Length();
                    if (Math.Abs(distance) <= Math.Abs(minDistance))
                    {
                        minDistance = distance;
                        param       = t[i];
                    }
                }
            }

            if (param >= 0 && param <= 1)
            {
                return(new SignedDistance(minDistance, 0));
            }
            if (param < .5)
            {
                return(new SignedDistance(minDistance, Math.Abs(Vector2.dotProduct(ab.normalize(), qa.normalize()))));
            }
            else
            {
                return(new SignedDistance(minDistance, Math.Abs(Vector2.dotProduct((p[2] - p[1]).normalize(), (p[2] - origin).normalize()))));
            }
        }
Exemplo n.º 5
0
        public override SignedDistance signedDistance(Vector2 origin, out double param)
        {
            Vector2 qa    = p[0] - origin;
            Vector2 ab    = p[1] - p[0];
            Vector2 br    = p[2] - p[1] - ab;
            Vector2 as_   = (p[3] - p[2]) - (p[2] - p[1]) - br;
            Vector2 epDir = direction(0);

            double minDistance = nonZeroSign(Vector2.crossProduct(epDir, qa)) * qa.Length(); // distance from A

            param = -Vector2.dotProduct(qa, epDir) / Vector2.dotProduct(epDir, epDir);
            {
                epDir = direction(1);
                double distance = nonZeroSign(Vector2.crossProduct(epDir, p[3] - origin)) * (p[3] - origin).Length(); // distance from B
                if (EquationSolver.fabs(distance) < EquationSolver.fabs(minDistance))
                {
                    minDistance = distance;
                    param       = Vector2.dotProduct(origin + epDir - p[3], epDir) / Vector2.dotProduct(epDir, epDir);
                }
            }
            // Iterative minimum distance search
            for (int i = 0; i <= MSDFGEN_CUBIC_SEARCH_STARTS; ++i)
            {
                double t = (double)((double)i / MSDFGEN_CUBIC_SEARCH_STARTS);
                for (int step = 0; ; ++step)
                {
                    Vector2 qpt      = point(t) - origin;
                    double  distance = nonZeroSign(Vector2.crossProduct(direction(t), qpt)) * qpt.Length();

                    if (EquationSolver.fabs(distance) < EquationSolver.fabs(minDistance))
                    {
                        minDistance = distance;
                        param       = t;
                    }
                    if (step == MSDFGEN_CUBIC_SEARCH_STEPS)
                    {
                        break;
                    }
                    // Improve t
                    Vector2 d1 = 3 * as_ * t * t + 6 * br * t + 3 * ab;
                    Vector2 d2 = 6 * as_ * t + 6 * br;
                    t -= Vector2.dotProduct(qpt, d1) / (Vector2.dotProduct(d1, d1) + Vector2.dotProduct(qpt, d2));
                    if (t < 0 || t > 1)
                    {
                        break;
                    }
                }
            }

            if (param >= 0 && param <= 1)
            {
                return(new SignedDistance(minDistance, 0));
            }
            if (param < .5)
            {
                return(new SignedDistance(minDistance,
                                          EquationSolver.fabs(Vector2.dotProduct(direction(0), qa.normalize()))));
            }
            else
            {
                return(new SignedDistance(minDistance,
                                          EquationSolver.fabs(Vector2.dotProduct(direction(1).normalize(), (p[3] - origin).normalize()))));
            }
        }