Exemple #1
0
        public static unsafe PointD Transform(this EGIS.Projections.ICoordinateTransformation @this, PointD pt, Projections.TransformDirection direction = Projections.TransformDirection.Forward)
        {
            PointD *ptr = &pt;

            @this.Transform((double *)ptr, 1, direction);
            return(pt);
        }
Exemple #2
0
        public static unsafe bool PointInPolygon(byte[] data, int offset, int numPoints, double x, double y, bool ignoreHoles, ref bool isHole)
        {
            if (ignoreHoles)
            {
                return(PointInPolygon(data, offset, numPoints, x, y));
            }

            //if we are detecting holes then we need to calculate the area
            double area   = 0;
            int    j      = numPoints - 1;
            bool   inPoly = false;

            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints; ++i)
                {
                    if (points[i].X < x && points[j].X >= x || points[j].X < x && points[i].X >= x)
                    {
                        if (points[i].Y + (x - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < y)
                        {
                            inPoly = !inPoly;
                        }
                    }
                    area += (points[j].X * points[i].Y - points[i].X * points[j].Y);
                    j     = i;
                }
            }

            area  *= 0.5;
            isHole = area > 0;
            return(inPoly);
        }
        public static unsafe void GetRgssOffsets(PointD *samplesArray, int sampleCount, int quality)
        {
            if (sampleCount < 1)
            {
                throw new ArgumentOutOfRangeException("sampleCount", "sampleCount must be [0, int.MaxValue]");
            }

            if (sampleCount != quality * quality)
            {
                throw new ArgumentOutOfRangeException("sampleCount != (quality * quality)");
            }

            if (sampleCount == 1)
            {
                samplesArray[0] = new PointD(0.0, 0.0);
            }
            else
            {
                for (int i = 0; i < sampleCount; ++i)
                {
                    double y = (i + 1d) / (sampleCount + 1d);
                    double x = y * quality;

                    x -= (int)x;

                    samplesArray[i] = new PointD(x - 0.5d, y - 0.5d);
                }
            }
        }
Exemple #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="numPoints"></param>
        /// <param name="centre"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        /// <remarks>Not tested</remarks>
        public static unsafe bool PolylineCircleIntersects(byte[] data, int offset, int numPoints, PointD centre, double radius)
        {
            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints - 1; i++)
                {
                    if (LineSegPointDist(ref points[i], ref points[i + 1], ref centre) <= radius)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #5
0
        public static unsafe bool PointOnPolyline(byte[] data, int offset, int numPoints, PointD pt, double minDist)
        {
            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints - 1; i++)
                {
                    if (LineSegPointDist(ref points[i], ref points[i + 1], ref pt) <= minDist)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Exemple #6
0
        public static unsafe bool IsPolygonHole(byte[] data, int offset, int numPoints)
        {
            //if we are detecting holes then we need to calculate the area
            double area = 0;
            int    j    = numPoints - 1;

            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints; ++i)
                {
                    area += (points[j].X * points[i].Y - points[i].X * points[j].Y);
                    j     = i;
                }
            }

            return(area > 0);
        }
Exemple #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <param name="numPoints"></param>6
        /// +
        /// <param name="centre"></param>
        /// <param name="radius"></param>
        /// <param name="ignoreHoles"></param>
        /// <returns></returns>
        /// <remarks>Not tested</remarks>
        public static unsafe bool PolygonCircleIntersects(byte[] data, int offset, int numPoints, PointD centre, double radius, bool ignoreHoles)
        {
            //test 1 : check if polygon intersects or is inside the circle
            //test the dist from each polygon edge to circle centre. If < radius then intersects
            int j = numPoints - 1;

            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints; ++i)
                {
                    //could optimize further by working with Distance Squared, but for the moment use the
                    //distance
                    if (LineSegPointDist(ref points[i], ref points[j], ref centre) <= radius)
                    {
                        return(true);
                    }
                    j = i;
                }
            }

            //test 2 : check if the circle is inside the polygon
            if (ignoreHoles)
            {
                return(PointInPolygon(data, offset, numPoints, centre.X, centre.Y));
            }
            //if a polygon is a hole then it doesn't intersect
            bool isHole = false;

            if (PointInPolygon(data, offset, numPoints, centre.X, centre.Y, false, ref isHole))
            {
                return(!isHole);
            }
            return(false);
        }
Exemple #8
0
        public static unsafe bool PointInPolygon(byte[] data, int offset, int numPoints, double x, double y)
        {
            int  j      = numPoints - 1;
            bool inPoly = false;

            fixed(byte *bPtr = data)
            {
                PointD *points = (PointD *)(bPtr + offset);

                for (int i = 0; i < numPoints; ++i)
                {
                    if (points[i].X < x && points[j].X >= x || points[j].X < x && points[i].X >= x)
                    {
                        if (points[i].Y + (x - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < y)
                        {
                            inPoly = !inPoly;
                        }
                    }
                    j = i;
                }
            }

            return(inPoly);
        }
Exemple #9
0
        public unsafe override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            float twist = Data.Amount;

            float hw     = dst.Width / 2.0f;
            float hh     = dst.Height / 2.0f;
            float maxrad = Math.Min(hw, hh);

            twist = twist * twist * Math.Sign(twist);

            int     aaLevel   = Data.Antialias;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                PointD pt = new PointD(
                    ((i * aaLevel) / (float)aaSamples),
                    i / (float)aaSamples);

                pt.X       -= (int)pt.X;
                aaPoints[i] = pt;
            }

            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y < rect.Bottom; y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);
                    ColorBgra *srcPtr = src.GetPointAddressUnchecked(src_data_ptr, src_width, rect.Left, y);

                    for (int x = rect.Left; x < rect.Right; x++)
                    {
                        float i = x - hw;

                        if (i * i + j * j > (maxrad + 1) * (maxrad + 1))
                        {
                            *dstPtr = *srcPtr;
                        }
                        else
                        {
                            int b = 0;
                            int g = 0;
                            int r = 0;
                            int a = 0;

                            for (int p = 0; p < aaSamples; ++p)
                            {
                                float  u     = i + (float)aaPoints[p].X;
                                float  v     = j + (float)aaPoints[p].Y;
                                double rad   = Math.Sqrt(u * u + v * v);
                                double theta = Math.Atan2(v, u);

                                double t = 1 - rad / maxrad;

                                t = (t < 0) ? 0 : (t * t * t);

                                theta += (t * twist) / 100;

                                ColorBgra sample = src.GetPointUnchecked(src_data_ptr, src_width,
                                                                         (int)(hw + (float)(rad * Math.Cos(theta))),
                                                                         (int)(hh + (float)(rad * Math.Sin(theta))));

                                b += sample.B;
                                g += sample.G;
                                r += sample.R;
                                a += sample.A;
                            }

                            *dstPtr = ColorBgra.FromBgra(
                                (byte)(b / aaSamples),
                                (byte)(g / aaSamples),
                                (byte)(r / aaSamples),
                                (byte)(a / aaSamples));
                        }

                        ++dstPtr;
                        ++srcPtr;
                    }
                }
            }
        }
Exemple #10
0
        unsafe public override void Render(ImageSurface src, ImageSurface dst, Gdk.Rectangle[] rois)
        {
            int   width     = dst.Width;
            int   height    = dst.Height;
            float hw        = width / 2f;
            float hh        = height / 2f;
            float sin       = (float)Math.Sin(Data.Rotation * Math.PI / 180.0);
            float cos       = (float)Math.Cos(Data.Rotation * Math.PI / 180.0);
            float scale     = (float)Math.PI / Data.TileSize;
            float intensity = Data.Intensity;

            intensity = intensity * intensity / 10 * Math.Sign(intensity);

            int     aaLevel   = 4;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                double x = (i * aaLevel) / (double)aaSamples;
                double y = i / (double)aaSamples;

                x -= (int)x;

                // RGSS + rotation to maximize AA quality
                aaPoints[i] = new PointD((double)(cos * x + sin * y), (double)(cos * y - sin * x));
            }

            int        src_width    = src.Width;
            ColorBgra *src_data_ptr = (ColorBgra *)src.DataPtr;

            foreach (var rect in rois)
            {
                for (int y = rect.Top; y <= rect.GetBottom(); y++)
                {
                    float      j      = y - hh;
                    ColorBgra *dstPtr = dst.GetPointAddressUnchecked(rect.Left, y);

                    for (int x = rect.Left; x <= rect.GetRight(); x++)
                    {
                        int   b = 0;
                        int   g = 0;
                        int   r = 0;
                        int   a = 0;
                        float i = x - hw;

                        for (int p = 0; p < aaSamples; ++p)
                        {
                            PointD pt = aaPoints[p];

                            float u = i + (float)pt.X;
                            float v = j - (float)pt.Y;

                            float s = cos * u + sin * v;
                            float t = -sin * u + cos * v;

                            s += intensity * (float)Math.Tan(s * scale);
                            t += intensity * (float)Math.Tan(t * scale);
                            u  = cos * s - sin * t;
                            v  = sin * s + cos * t;

                            int xSample = (int)(hw + u);
                            int ySample = (int)(hh + v);

                            xSample = (xSample + width) % width;
                            // This makes it a little faster
                            if (xSample < 0)
                            {
                                xSample = (xSample + width) % width;
                            }

                            ySample = (ySample + height) % height;
                            // This makes it a little faster
                            if (ySample < 0)
                            {
                                ySample = (ySample + height) % height;
                            }

                            ColorBgra sample = *src.GetPointAddressUnchecked(src_data_ptr, src_width, xSample, ySample);

                            b += sample.B;
                            g += sample.G;
                            r += sample.R;
                            a += sample.A;
                        }

                        *(dstPtr++) = ColorBgra.FromBgra((byte)(b / aaSamples), (byte)(g / aaSamples),
                                                         (byte)(r / aaSamples), (byte)(a / aaSamples));
                    }
                }
            }
        }
        private unsafe IGeometry ReadPolygon(int oid)
        {
            var dataPtr       = zeroPtr + recordHeaders[oid].Offset;
            var polygonRecord = (PolygonRecordP *)(dataPtr + 8);

            //First read all the rings
            int offset = polygonRecord->DataOffset;
            int parts  = polygonRecord->NumParts;

            var rings = new ILinearRing[parts];

            for (int part = 0; part < parts; ++part)
            {
                int points;

                if ((parts - part) > 1)
                {
                    points = polygonRecord->PartOffsets[part + 1] - polygonRecord->PartOffsets[part];
                }
                else
                {
                    points = polygonRecord->NumPoints - polygonRecord->PartOffsets[part];
                }
                if (points <= 1)
                {
                    continue;
                }

                var ring = new Coordinate[points];

                int     index    = 0;
                PointD *pointPtr = (PointD *)(dataPtr + 8 + offset + (polygonRecord->PartOffsets[part] << 4));
                PointD  point    = *(pointPtr++);

                ring[index] = GeometryFactoryEx.CreateCoordinate(point.X, point.Y);
                ++index;

                while (index < points)
                {
                    point       = *(pointPtr++);
                    ring[index] = GeometryFactoryEx.CreateCoordinate(point.X, point.Y);
                    ++index;
                }

                // polygon should be closed, try to fix
                if (!ring[ring.Length - 1].Equals2D(ring[0]))
                {
                    ring[ring.Length - 1] = GeometryFactoryEx.CreateCoordinate(ring[0].X, ring[0].Y);
                }

                rings[part] = GeometryFactory.CreateLinearRing(ring);
            }

            if (rings.Length == 1) //We only have one polygon
            {
                ILinearRing shell = rings[0];
                if (rings.Length > 1)
                {
                    var holes = new ILinearRing[rings.Length];
                    for (int i = 1; i < rings.Length; i++)
                    {
                        holes[i] = rings[i];
                    }
                    return(GeometryFactory.CreatePolygon(shell, holes));
                }

                return(GeometryFactory.CreatePolygon(shell, null));
            }
            else
            {
                var         polys = new List <IPolygon>();
                ILinearRing shell = rings[0];
                var         holes = new List <ILinearRing>();
                for (int i = 1; i < rings.Length; i++)
                {
                    if (!GeometryFactory.IsCCW(rings[i].Coordinates))
                    {
                        polys.Add(GeometryFactory.CreatePolygon(shell, null));
                        shell = rings[i];
                    }
                    else
                    {
                        holes.Add(rings[i]);
                    }
                }

                polys.Add(GeometryFactory.CreatePolygon(shell, holes.ToArray()));
                return(GeometryFactory.CreateMultiPolygon(polys.ToArray()));
            }
        }
        protected unsafe override void RenderLine(ISurface src, ISurface dst, Rectangle rect)
        {
            int   width     = dst.Width;
            int   height    = dst.Height;
            float hw        = width / 2f;
            float hh        = height / 2f;
            float sin       = (float)Math.Sin(rotation * Math.PI / 180.0);
            float cos       = (float)Math.Cos(rotation * Math.PI / 180.0);
            float scale     = (float)Math.PI / tile_size;
            float intensity = tile_size;

            intensity = intensity * intensity / 10 * Math.Sign(intensity);

            int     aaLevel   = 4;
            int     aaSamples = aaLevel * aaLevel + 1;
            PointD *aaPoints  = stackalloc PointD[aaSamples];

            for (int i = 0; i < aaSamples; ++i)
            {
                double x = (i * aaLevel) / (double)aaSamples;
                double y = i / (double)aaSamples;

                x -= (int)x;

                // RGSS + rotation to maximize AA quality
                aaPoints[i] = new PointD((double)(cos * x + sin * y), (double)(cos * y - sin * x));
            }

            for (int y = rect.Top; y <= rect.Bottom; y++)
            {
                float      j      = y - hh;
                ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                for (int x = rect.Left; x <= rect.Right; x++)
                {
                    int   b = 0;
                    int   g = 0;
                    int   r = 0;
                    int   a = 0;
                    float i = x - hw;

                    for (int p = 0; p < aaSamples; ++p)
                    {
                        PointD pt = aaPoints[p];

                        float u = i + (float)pt.X;
                        float v = j - (float)pt.Y;

                        float s = cos * u + sin * v;
                        float t = -sin * u + cos * v;

                        s += intensity * (float)Math.Tan(s * scale);
                        t += intensity * (float)Math.Tan(t * scale);
                        u  = cos * s - sin * t;
                        v  = sin * s + cos * t;

                        int xSample = (int)(hw + u);
                        int ySample = (int)(hh + v);

                        xSample = (xSample + width) % width;
                        // This makes it a little faster
                        if (xSample < 0)
                        {
                            xSample = (xSample + width) % width;
                        }

                        ySample = (ySample + height) % height;
                        // This makes it a little faster
                        if (ySample < 0)
                        {
                            ySample = (ySample + height) % height;
                        }

                        ColorBgra sample = *src.GetPointAddress(xSample, ySample);

                        b += sample.B;
                        g += sample.G;
                        r += sample.R;
                        a += sample.A;
                    }

                    *(dstPtr++) = ColorBgra.FromBgra((byte)(b / aaSamples), (byte)(g / aaSamples),
                                                     (byte)(r / aaSamples), (byte)(a / aaSamples));
                }
            }
        }
Exemple #13
0
        protected unsafe override void RenderLine(ISurface src, ISurface dst, Rectangle rect)
        {
            ColorBgra colTransparent = ColorBgra.Transparent;

            int     aaSampleCount = quality * quality;
            PointD *aaPoints      = stackalloc PointD[aaSampleCount];

            Utility.GetRgssOffsets(aaPoints, aaSampleCount, quality);
            ColorBgra *samples = stackalloc ColorBgra[aaSampleCount];

            TransformData td;

            for (int y = rect.Top; y <= rect.Bottom; y++)
            {
                ColorBgra *dstPtr = dst.GetPointAddress(rect.Left, y);

                double relativeY = y - center_offset.Y;

                for (int x = rect.Left; x <= rect.Right; x++)
                {
                    double relativeX = x - center_offset.X;

                    int sampleCount = 0;

                    for (int p = 0; p < aaSampleCount; ++p)
                    {
                        td.X = relativeX + aaPoints[p].X;
                        td.Y = relativeY - aaPoints[p].Y;

                        InverseTransform(ref td);

                        float sampleX = (float)(td.X + center_offset.X);
                        float sampleY = (float)(td.Y + center_offset.Y);

                        ColorBgra sample = primary_color;

                        if (IsOnSurface(src, sampleX, sampleY))
                        {
                            sample = Utility.GetBilinearSampleClamped(src, sampleX, sampleY);
                        }
                        else
                        {
                            switch (edge_behavior)
                            {
                            case WarpEdgeBehavior.Clamp:
                                sample = Utility.GetBilinearSampleClamped(src, sampleX, sampleY);
                                break;

                            case WarpEdgeBehavior.Wrap:
                                sample = Utility.GetBilinearSampleWrapped(src, sampleX, sampleY);
                                break;

                            case WarpEdgeBehavior.Reflect:
                                sample = Utility.GetBilinearSampleClamped(src, ReflectCoord(sampleX, src.Width), ReflectCoord(sampleY, src.Height));

                                break;

                            case WarpEdgeBehavior.Primary:
                                sample = primary_color;
                                break;

                            case WarpEdgeBehavior.Secondary:
                                sample = secondary_color;
                                break;

                            case WarpEdgeBehavior.Transparent:
                                sample = colTransparent;
                                break;

                            case WarpEdgeBehavior.Original:
                                sample = src.GetPoint(x, y);
                                break;

                            default:

                                break;
                            }
                        }

                        samples[sampleCount] = sample;
                        ++sampleCount;
                    }

                    *dstPtr = ColorBgra.Blend(samples, sampleCount);
                    ++dstPtr;
                }
            }
        }