Пример #1
0
        public static T EdgeEval(ContourVertex <T> u, ContourVertex <T> v, ContourVertex <T> w)
        {
            /* Given three vertices u,v,w such that VertLeq(u,v) && VertLeq(v,w),
             * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
             * Returns v.t - (uw)(v.s), ie. the signed distance from uw to v.
             * If uw is vertical (and thus passes thru v), the result is zero.
             *
             * The calculation is extremely accurate and stable, even when v
             * is very close to u or w.  In particular if we set v.t = 0 and
             * let r be the negated result (this evaluates (uw)(v.s)), then
             * r is guaranteed to satisfy MIN(u.t,w.t) <= r <= MAX(u.t,w.t).
             */
            T gapL, gapR;

            if (!((u.VertLeq(u) && v.VertLeq(v))))
            {
                throw new Exception();
            }

            gapL = v.x.Subtract(u.x);
            gapR = w.x.Subtract(v.x);

            if (gapL.Add(gapR).GreaterThan(0))
            {
                if (gapL.LessThan(gapR))
                {
                    return(v.y.Subtract(u.y).Add(
                               u.y.Subtract(w.y).Multiply(
                                   gapL.Divide(gapL.Add(gapR)))));
                }
                else
                {
                    return(v.y.Subtract(w.y).Add(w.y.Subtract(u.y).Multiply(gapR.Divide(gapL.Add(gapR)))));
                }
            }

            // vertical line
            return(M.Zero <T>());
        }
Пример #2
0
        static public T EdgeSign(ContourVertex <T> u, ContourVertex <T> v, ContourVertex <T> w)
        {
            /* Returns a number whose sign matches EdgeEval(u,w) but which
             * is cheaper to evaluate.  Returns > 0, == 0 , or < 0
             * as v is above, on, or below the edge uw.
             */
            T gapL, gapR;

            if (!u.VertLeq(v) || !v.VertLeq(w))
            {
                throw new System.Exception();
            }

            gapL = v.x.Subtract(u.x);
            gapR = w.x.Subtract(v.x);

            if (gapL.Add(gapR).GreaterThan(0))
            {
                return(v.y.Subtract(w.y).Multiply(gapL).Add(v.y.Subtract(u.y).Multiply(gapR)));
            }
            /* vertical line */
            return(M.Zero <T>());
        }