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); }
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); } } }
/// <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); }
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); }
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); }
/// <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); }
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); }
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; } } } }
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)); } } }
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; } } }