Beispiel #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);
            }
        }
Beispiel #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);
            }
        }
Beispiel #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);
        }
Beispiel #4
0
 internal override void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     lcb(X, Y, false);
     penx = X;
     peny = Y;
 }
Beispiel #5
0
 internal virtual void Flatten(ref double penx, ref double peny, double tol, FlattenCallback lcb)
 {
     lcb(X, Y, true);
     penx = X;
     peny = Y;
 }
Beispiel #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);
        }
Beispiel #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;
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
            }
        }
Beispiel #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);
        }
Beispiel #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);
        }
Beispiel #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);
            }
        }
Beispiel #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;
 }
Beispiel #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;
 }
Beispiel #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;
 }
Beispiel #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);
 }