Пример #1
0
        public void Flatten(double tol, FlattenCallback lcb)
        {
            double penx = 0.0, peny = 0.0;

            foreach (GFXPathMoveTo node in PathPoints)
            {
                node.Flatten(ref penx, ref peny, tol, lcb);
            }
        }
Пример #2
0
        public void TransformFlatten(double tol, Transform2d t, FlattenCallback lcb)
        {
            double penx = 0.0, peny = 0.0;

            foreach (GFXPathMoveTo node in PathPoints)
            {
                node.TransformFlatten(ref penx, ref peny, tol, t, lcb);
            }
        }
Пример #3
0
        internal override void TransformFlatten(ref double penx, ref double peny, double tol, Transform2d t, FlattenCallback lcb)
        {
            penx = X;
            peny = Y;
            double tx, ty;

            t.Apply(penx, peny, out tx, out ty, true);
            lcb(tx, ty, false);
        }
Пример #4
0
 internal override void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     lcb(X, Y, false);
     penx = X;
     peny = Y;
 }
Пример #5
0
 internal virtual void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     lcb(X, Y, true);
     penx = X;
     peny = Y;
 }
Пример #6
0
        public static void FlattenArcInternal(double x1, double y1, double x2, double y2, double bulge, double flattentolerance, FlattenCallback cb)
        {
            double chord    = Math.Sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));
            double altitude = -chord * bulge * 0.5;

            if (Math.Abs(altitude) < flattentolerance)
            {
                cb(x2, y2, false);
                return;
            }

            double midx = (x2 + x1) * 0.5;
            double midy = (y2 + y1) * 0.5;

            double vx  = x2 - x1;
            double vy  = y2 - y1;
            double fac = altitude / chord;

            vx   *= fac;
            vy   *= fac;
            midx -= vy;
            midy += vx;

            //compute new bulge factor for half of arc:
            bulge = Math.Tan(0.5 * Math.Atan(bulge));

            FlattenArcInternal(x1, y1, midx, midy, bulge, flattentolerance, cb);
            FlattenArcInternal(midx, midy, x2, y2, bulge, flattentolerance, cb);
        }
Пример #7
0
        internal override void TransformFlatten(ref double penx, ref double peny, double tol, Transform2d t, FlattenCallback lcb)
        {
            double xs, ys, c1x, c1y, c2x, c2y, xe, ye;

            t.Apply(penx, peny, out xs, out ys, true);
            t.Apply(XC1, YC1, out c1x, out c1y, true);
            t.Apply(XC2, YC2, out c2x, out c2y, true);
            t.Apply(X, Y, out xe, out ye, true);
            GeomUtil.FlattenBezier(xs, ys, c1x, c1y, c2x, c2y, xe, ye, false, tol, lcb);
            penx = X;
            peny = Y;
        }
Пример #8
0
        private static void _TransformFlattenArcUniform(double x1, double y1, double x2, double y2, double bulge, double sqrtol, Transform2d t, FlattenCallback cb)
        {
            //vector from middle of chord to point on arc:
            double midvx = (y2 - y1) * bulge * 0.5;
            double midvy = -(x2 - x1) * bulge * 0.5;

            //transformed error vector:
            double errvx, errvy, midx, midy;

            t.Apply(midvx, midvy, out errvx, out errvy, false); //transform error vector

            if (errvx * errvx + errvy * errvy < sqrtol)
            {
                t.Apply(x2, y2, out x2, out y2, true);
                cb(x2, y2, false);
                return;
            }

            midx = (x2 + x1) * 0.5 + midvx;
            midy = (y2 + y1) * 0.5 + midvy;



            //compute new bulge factor for half of arc:
            bulge = Math.Tan(0.5 * Math.Atan(bulge));
            _TransformFlattenArcUniform(x1, y1, midx, midy, bulge, sqrtol, t, cb);
            _TransformFlattenArcUniform(midx, midy, x2, y2, bulge, sqrtol, t, cb);
        }
Пример #9
0
        private static void InternalTransformFlattenArcNonUniform(double x1, double y1, double x2, double y2, double bulge, double tx1, double ty1, double tx2, double ty2, double sqrtol, Transform2d t, FlattenCallback cb)
        {
            //tx1,ty1,tx2,ty2 is x1,y1,x2,y2 transformed (to save computation time we dont recompute thoose evry recursion)


            //vector from middle of chord to point on arc:
            double midvx = (y2 - y1) * bulge * 0.5;
            double midvy = -(x2 - x1) * bulge * 0.5;

            //transformed error vector:
            double errvx, errvy, midx, midy;

            t.Apply(midvx, midvy, out errvx, out errvy, false); //transform error vector

            //midpoint on non-transformed arc
            midx = (x2 + x1) * 0.5 + midvx;
            midy = (y2 + y1) * 0.5 + midvy;


            //non uniform transform: must check error point on (ellipse):s distance to the chordline:
            double tmx, tmy;    //transformed midpoint

            t.Apply(midx, midy, out tmx, out tmy, true);
            double err = InfiniteLinePointDistance(tx1, ty1, tx2, ty2, tmx, tmy);

            if (err * err < sqrtol)
            {
                cb(tx2, ty2, false);
                return;
            }

            //compute new bulge factor for half of arc:
            bulge = Math.Tan(0.5 * Math.Atan(bulge));
            InternalTransformFlattenArcNonUniform(x1, y1, midx, midy, bulge, tx1, ty1, tmx, tmy, sqrtol, t, cb);
            InternalTransformFlattenArcNonUniform(midx, midy, x2, y2, bulge, tmx, tmy, tx2, ty2, sqrtol, t, cb);
        }
Пример #10
0
        public static void FlattenEllipse(double centerx, double centery, double aradius, double bradius, double tilt, double flattentol, bool firstpoint, FlattenCallback lcb)
        {
            //draw it as a transformed unit size arcs
            double      cst = Math.Cos(tilt);
            double      sit = Math.Sin(tilt);
            Transform2d tr  = new Transform2d(Math.Cos(tilt) * aradius, Math.Sin(tilt) * aradius, Math.Cos(tilt + MathUtil.Deg90) * bradius, Math.Sin(tilt + MathUtil.Deg90) * bradius, centerx, centery);

            TransformFlattenArc(1.0, 0.0, -1.0, 0.0, 1.0, firstpoint, flattentol, tr, lcb);
            TransformFlattenArc(-1.0, 0.0, 1.0, 0.0, 1.0, false, flattentol, tr, lcb);
        }
Пример #11
0
        public static void TransformFlattenArc(double x1, double y1, double x2, double y2, double bulge, bool firstpoint, double tol, Transform2d t, FlattenCallback lcb)
        {
            if (firstpoint)
            {
                double tx1, ty1;
                t.Apply(x1, y1, out tx1, out ty1, true);
                lcb(tx1, ty1, true);
            }

            bool uniform = t.IsUniform;

            if (t.IsUniform)
            {
                if (firstpoint)
                {
                    double tx1, ty1;
                    t.Apply(x1, y1, out tx1, out ty1, true);
                    lcb(tx1, ty1, true);
                }

                _TransformFlattenArcUniform(x1, y1, x2, y2, bulge, tol * tol, t, lcb);
            }
            else
            {
                double tx1, ty1, tx2, ty2;
                t.Apply(x1, y1, out tx1, out ty1, true);
                t.Apply(x2, y2, out tx2, out ty2, true); //pre-compute transformed points

                if (firstpoint)
                {
                    lcb(tx1, ty1, true);
                }

                InternalTransformFlattenArcNonUniform(x1, y1, x2, y2, bulge, tx1, ty1, tx2, ty2, tol * tol, t, lcb);
            }
        }
Пример #12
0
        public static void FlattenEllipticArc(double centerx, double centery, double aradius, double bradius, double tilt, double startangle, double sweepangle, double flattentol, bool firstpoint, FlattenCallback lcb)
        {
            //check if full ellipse
            if (Math.Abs(sweepangle) >= MathUtil.Deg360 - MathUtil.Epsilon)
            {
                FlattenEllipse(centerx, centery, aradius, bradius, tilt, flattentol, firstpoint, lcb);
                return;
            }

            double startparam = EllipseAngleToParam(startangle, aradius, bradius);
            double endparam   = EllipseAngleToParam(startangle + sweepangle, aradius, bradius);
            double sweepparam;

            if (sweepangle > 0.0) //ccw
            {
                while (endparam < startparam)
                {
                    endparam += MathUtil.Deg360;
                }
                sweepparam = endparam - startparam;
            }
            else
            { //cw
                while (endparam > startparam)
                {
                    endparam -= MathUtil.Deg360;
                }
                sweepparam = endparam - startparam;
            }

            //draw it as a transformed unit size arc
            double      cst   = Math.Cos(tilt);
            double      sit   = Math.Sin(tilt);
            Transform2d tr    = new Transform2d(Math.Cos(tilt) * aradius, Math.Sin(tilt) * aradius, Math.Cos(tilt + MathUtil.Deg90) * bradius, Math.Sin(tilt + MathUtil.Deg90) * bradius, centerx, centery);
            double      x1    = Math.Cos(startparam);
            double      y1    = Math.Sin(startparam);
            double      x2    = Math.Cos(endparam);
            double      y2    = Math.Sin(endparam);
            double      bulge = GetArcBulgeFromSweepAngle(sweepparam); //should work with negative sweeps as well

            TransformFlattenArc(x1, y1, x2, y2, bulge, firstpoint, flattentol, tr, lcb);
        }
Пример #13
0
        static void FlattenBezierInternal(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4,
                                          double t1, double t1x, double t1y, double t2, double t2x, double t2y, double sqrtol, FlattenCallback cb)
        {
            double midx, midy, midt = (t1 + t2) / 2.0;

            EvalBezier(x1, y1, x2, y2, x3, y3, x4, y4, midt, out midx, out midy);
            if (SquaredDistance((t1x + t2x) / 2.0, (t1y + t2y) / 2.0, midx, midy) > sqrtol)
            {
                FlattenBezierInternal(x1, y1, x2, y2, x3, y3, x4, y4, t1, t1x, t1y, midt, midx, midy, sqrtol, cb);
                FlattenBezierInternal(x1, y1, x2, y2, x3, y3, x4, y4, midt, midx, midy, t2, t2x, t2y, sqrtol, cb);
            }

            cb(t2x, t2y, false);
        }
Пример #14
0
        public static void FlattenBezier(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4, bool firstpoint, double flattentolerance, FlattenCallback cb, double t1 = 0.0, double t2 = 1.0)
        {
            double sqrtol = flattentolerance * flattentolerance;
            double midt   = (t1 + t2) * 0.5;

            //check if estimation line passes thru curve at parametric midpoint, if so split at middle t
            //otherwise just recurse:
            double midx, midy, t1x, t1y, t2x, t2y;

            if (t1 == 0.0)
            {
                t1x = x1;
                t1y = y1;
            }
            else
            {
                EvalBezier(x1, y1, x2, y2, x3, y3, x4, y4, t1, out t1x, out t1y);
            }

            if (t2 == 1.0)
            {
                t2x = x4;
                t2y = y4;
            }
            else
            {
                EvalBezier(x1, y1, x2, y2, x3, y3, x4, y4, t2, out t2x, out t2y);
            }


            if (firstpoint)
            {
                cb(t1x, t1y, true);
            }


            EvalBezier(x1, y1, x2, y2, x3, y3, x4, y4, midt, out midx, out midy);

            double tdist = SquaredDistance((t1x + t2x) / 2.0, (t1y + t2y) / 2.0, midx, midy);

            if (tdist <= sqrtol)
            {
                FlattenBezierInternal(x1, y1, x2, y2, x3, y3, x4, y4, t1, t1x, t1y, midt, midx, midy, sqrtol, cb);
                FlattenBezierInternal(x1, y1, x2, y2, x3, y3, x4, y4, midt, midx, midy, t2, t2x, t2y, sqrtol, cb);
            }
            else
            {
                FlattenBezierInternal(x1, y1, x2, y2, x3, y3, x4, y4, t1, t1x, t1y, t2, t2x, t2y, sqrtol, cb);
            }
        }
Пример #15
0
 internal override void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     GeomUtil.FlattenArc(penx, peny, X, Y, Bulge, false, tol, lcb);
     penx = X;
     peny = Y;
 }
Пример #16
0
 internal override void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     GeomUtil.FlattenBezier(penx, peny, XC1, YC1, XC2, YC2, X, Y, false, tol, lcb);
     penx = X;
     peny = Y;
 }
Пример #17
0
 internal override void TransformFlatten(ref double penx, ref double peny, double tol, Transform2d t, FlattenCallback lcb)
 {
     GeomUtil.TransformFlattenArc(penx, peny, X, Y, Bulge, false, tol, t, lcb);
     penx = X;
     peny = Y;
 }
Пример #18
0
 public static void FlattenArc(double x1, double y1, double x2, double y2, double bulge, bool firstpoint, double flattentolerance, FlattenCallback cb)
 {
     if (firstpoint)
     {
         cb(x1, y1, true);
     }
     FlattenArcInternal(x1, y1, x2, y2, bulge, flattentolerance, cb);
 }