Ejemplo n.º 1
0
        // -------------------------------------------------
        // Util
        // -------------------------------------------------

        private static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> points, bool closed, Geometry.Unit unit)
        {
            Geometry.Interval result = null;

            if (points.Count < 1)
            {
                result = new Geometry.Interval();
                Geometry.AssignInverse(result);
                return(result);
            }

            double x0 = points[0][0];

            result = new Geometry.Interval(x0);

            int count = points.Count + (closed ? 1 : 0);

            for (int ii = 1; ii < count; ++ii)
            {
                int    i        = ii % points.Count;
                double xi       = points[i][0];
                double distNorm = Geometry.NormalizedAngleSigned(xi - x0, unit); // [-pi, pi]
                double x1       = x0 + distNorm;
                result.Expand(x1);
                x0 = x1;
            }
            return(result);
        }
Ejemplo n.º 2
0
            public PeriodicDrawableBox(LocalCS cs,
                                       Geometry.IRandomAccessRange <Geometry.Point> points,
                                       Geometry.Unit unit)
                : base(true)
            {
                int count = points.Count + 1;

                xs_orig    = new float[count];
                points_rel = new PointF[count];

                xs_orig[0]    = cs.ConvertX(points[0][0]);
                points_rel[0] = cs.Convert(points[0]);

                for (int i = 1; i < points.Count; ++i)
                {
                    xs_orig[i] = cs.ConvertX(points[i][0]);

                    // always relative to p0
                    double distNorm = Geometry.NormalizedAngleUnsigned(points[i][0] - points[0][0], unit); // [0, 2pi] - min is always lesser than max

                    double x_curr = points[0][0] + distNorm;                                               // always relative to p0
                    points_rel[i] = new PointF(cs.ConvertX(x_curr),
                                               cs.ConvertY(points[i][1]));
                }

                // close
                xs_orig[points.Count]    = xs_orig[0];
                points_rel[points.Count] = points_rel[0];
            }
Ejemplo n.º 3
0
            public PeriodicDrawablePolygon(LocalCS cs,
                                           Geometry.IRandomAccessRange <Geometry.Point> outer,
                                           IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners,
                                           Geometry.Box box,
                                           Geometry.Unit unit)
            {
                this.outer = new PeriodicDrawableRange(cs, outer, box, unit);

                minf     = this.outer.minf;
                maxf     = this.outer.maxf;
                periodf  = this.outer.periodf;
                box_minf = this.outer.box_minf;
                box_maxf = this.outer.box_maxf;

                this.inners = new List <PeriodicDrawableRange>();
                int i = 0;

                foreach (var inner in inners)
                {
                    this.inners.Add(new PeriodicDrawableRange(cs, inner, box, unit));

                    // expand relative box X
                    if (this.inners[i].minf < minf)
                    {
                        minf = this.inners[i].minf;
                    }
                    if (this.inners[i].maxf > maxf)
                    {
                        maxf = this.inners[i].maxf;
                    }
                }
            }
Ejemplo n.º 4
0
 public static Geometry.Interval RelativeEnvelopeLon(Geometry.IRandomAccessRange <Geometry.Point> outer,
                                                     IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners,
                                                     Geometry.Unit unit)
 {
     Geometry.Interval result = RelativeEnvelopeLon(outer, true, unit);
     foreach (var inner in inners)
     {
         result.Expand(RelativeEnvelopeLon(inner, true, unit));
     }
     return(result);
 }
Ejemplo n.º 5
0
            public PeriodicDrawableRange(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit)
            {
                if (points.Count < 2)
                {
                    return;
                }

                double pi = Geometry.HalfAngle(unit);

                periodf = cs.ConvertDimension(2 * pi);

                xs_orig    = new float[points.Count];
                points_rel = new PointF[points.Count];

                xs_orig[0]    = cs.ConvertX(points[0][0]);
                points_rel[0] = cs.Convert(points[0]);

                minf = points_rel[0].X;
                maxf = points_rel[0].X;

                double x0      = Geometry.NormalizedAngle(points[0][0], unit);
                double x0_prev = points[0][0];

                for (int i = 1; i < points.Count; ++i)
                {
                    xs_orig[i] = cs.ConvertX(points[i][0]);

                    double x1       = Geometry.NormalizedAngle(points[i][0], unit);
                    double dist     = x1 - x0;                              // [-2pi, 2pi]
                    double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi]

                    double x0_curr = x0_prev + distNorm;
                    points_rel[i] = new PointF(cs.ConvertX(x0_curr),
                                               cs.ConvertY(points[i][1]));

                    // expand relative box X
                    if (points_rel[i].X < minf)
                    {
                        minf = points_rel[i].X;
                    }
                    if (points_rel[i].X > maxf)
                    {
                        maxf = points_rel[i].X;
                    }

                    x0_prev = x0_curr;
                    x0      = x1;
                }

                box_minf = cs.ConvertX(box.Min[0]);
                box_maxf = cs.ConvertX(box.Max[0]);
            }
Ejemplo n.º 6
0
            public PeriodicDrawablePolygon(LocalCS cs,
                                           Geometry.IRandomAccessRange <Geometry.Point> outer,
                                           IEnumerable <Geometry.IRandomAccessRange <Geometry.Point> > inners,
                                           Geometry.Unit unit,
                                           bool densify)
            {
                this.outer = new PeriodicDrawableRange(cs, outer, true, unit, densify);

                this.inners = new List <PeriodicDrawableRange>();
                foreach (var inner in inners)
                {
                    PeriodicDrawableRange pd = new PeriodicDrawableRange(cs, inner, true, unit, densify);
                    this.inners.Add(pd);
                }
            }
Ejemplo n.º 7
0
            public PeriodicDrawableBox(LocalCS cs, Geometry.IRandomAccessRange <Geometry.Point> points, Geometry.Box box, Geometry.Unit unit)
            {
                double pi = Geometry.HalfAngle(unit);

                periodf = cs.ConvertDimension(2 * pi);

                xs_orig    = new float[points.Count];
                points_rel = new PointF[points.Count];

                xs_orig[0]    = cs.ConvertX(points[0][0]);
                points_rel[0] = cs.Convert(points[0]);

                minf = points_rel[0].X;
                maxf = points_rel[0].X;

                double x0 = Geometry.NormalizedAngle(points[0][0], unit);

                for (int i = 1; i < points.Count; ++i)
                {
                    xs_orig[i] = cs.ConvertX(points[i][0]);

                    double x1       = Geometry.NormalizedAngle(points[i][0], unit);
                    double dist     = x1 - x0;                              // [-2pi, 2pi]
                    double distNorm = Geometry.NormalizedAngle(dist, unit); // [-pi, pi]
                    while (distNorm < 0)
                    {
                        distNorm += 2 * Geometry.HalfAngle(unit); // [0, 2pi] - min is always lesser than max
                    }
                    double x0_curr = points[0][0] + distNorm;     // always relative to p0
                    points_rel[i] = new PointF(cs.ConvertX(x0_curr),
                                               cs.ConvertY(points[i][1]));

                    // expand relative box X
                    if (points_rel[i].X < minf)
                    {
                        minf = points_rel[i].X;
                    }
                    if (points_rel[i].X > maxf)
                    {
                        maxf = points_rel[i].X;
                    }
                }

                box_minf = cs.ConvertX(box.Min[0]);
                box_maxf = cs.ConvertX(box.Max[0]);
            }
Ejemplo n.º 8
0
        public PointF[] Convert(Geometry.IRandomAccessRange <Geometry.Point> points)
        {
            if (points.Count <= 0)
            {
                return(null);
            }

            int dst_count = points.Count + (points[0] == points[points.Count - 1] ? 0 : 1);

            PointF[] dst_points = new PointF[dst_count];
            int      i          = 0;

            for (; i < points.Count; ++i)
            {
                dst_points[i] = Convert(points[i]);
            }
            if (i < dst_count)
            {
                dst_points[i] = Convert(points[0]);
            }

            return(dst_points);
        }
Ejemplo n.º 9
0
            public PeriodicDrawableRange(LocalCS cs,
                                         Geometry.IRandomAccessRange <Geometry.Point> points,
                                         bool closed,
                                         Geometry.Unit unit,
                                         bool densify)
            {
                this.closed       = closed;
                this.containsPole = ContainsPole.No;

                if (points.Count < 2)
                {
                    return;
                }

                // approx. length of densified segments

                /*double densLength = Math.Min(cs.InverseConvertDimensionX(20),
                 *                           cs.InverseConvertDimensionY(20));*/
                double densLength = Geometry.FromDegree(5, unit);

                int count = points.Count + (closed ? 1 : 0);

                xs_orig    = new float[count];
                points_rel = new PointF[count];
                if (densify)
                {
                    dens_points_rel = new PointF[points.Count][];
                }

                xs_orig[0]    = cs.ConvertX(points[0][0]);
                points_rel[0] = cs.Convert(points[0]);

                Geometry.Point p0 = points[0].Clone();
                for (int i = 1; i < count; ++i)
                {
                    Geometry.Point p1 = points[i % points.Count].Clone();

                    xs_orig[i] = cs.ConvertX(p1[0]);

                    double distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi]
                    p1[0]         = p0[0] + distNorm;
                    points_rel[i] = cs.Convert(p1);

                    if (dens_points_rel != null)
                    {
                        dens_points_rel[i - 1] = DensifyAndConvert(cs, p0, p1, densLength, unit);
                    }

                    p0 = p1;
                }

                if (closed && Math.Abs(points_rel[0].X - points_rel[points.Count].X) > 0.1)
                {
                    // Check which pole
                    double area = 0;
                    p0 = points[0].Clone();
                    for (int i = 1; i < count; ++i)
                    {
                        Geometry.Point p1       = points[i % points.Count].Clone();
                        double         distNorm = Geometry.NormalizedAngleSigned(p1[0] - p0[0], unit); // [-pi, pi]
                        p1[0] = p0[0] + distNorm;
                        area += Geometry.SphericalTrapezoidArea(p0, p1, unit);
                        p0    = p1;
                    }

                    int areaSign = Math.Sign(area);
                    int dirSign  = Math.Sign(points_rel[points.Count].X - points_rel[0].X);
                    this.containsPole = (areaSign * dirSign >= 0)
                                      ? ContainsPole.North
                                      : ContainsPole.South;
                }
            }
Ejemplo n.º 10
0
 private static Geometry.Box AabbRange(Geometry.IRandomAccessRange <Geometry.Point> rng, bool closed, Geometry.Traits traits, bool calculateEnvelope)
 {
     return(calculateEnvelope
          ? Geometry.Envelope(rng, closed, traits)
          : Geometry.Aabb(rng, closed, traits.Unit));
 }