private static bool LineToLine(Vertex2 vertex1, Vertex2 vertex2, Vertex2 vertex3, Vertex2 vertex4, out float r, out float s) { r = 0; s = 0; //Make sure the lines aren't parallel Vertex2 line1 = vertex2 - vertex1; Vertex2 line2 = vertex4 - vertex3; //if (vertex1to2.x * -vertex3to4.y + vertex1to2.y * vertex3to4.x != 0) //{ //if (line1.y/line1.x != line2.y/line2.x) //{ //} float d = PGUtils.PerpDot(line1, line2); if (d != 0) { Vertex2 vertex3to1 = vertex1 - vertex3; r = (vertex3to1.y * line2.x - vertex3to1.x * line2.y) / d; s = (vertex3to1.y * line1.x - vertex3to1.x * line1.y) / d; return(true); } else { //Parallel } return(false); }
public static void BresenhamLine(int x0, int y0, int x1, int y1, Action <int, int> draw) { bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); if (steep) { PGUtils.Swap(ref x0, ref y0); PGUtils.Swap(ref x1, ref y1); } if (x0 > x1) { PGUtils.Swap(ref x0, ref x1); PGUtils.Swap(ref y0, ref y1); } int dx = x1 - x0; int dy = Math.Abs(y1 - y0); int error = dx / 2; int ystep = (y0 < y1) ? 1 : -1; int y = y0; for (int x = x0; x <= x1; x++) { draw(steep ? y : x, steep ? x : y); error -= dy; if (error < 0) { y += ystep; error += dx; } } }
public bool Contains(Vertex2 point, out int wn) { wn = 0; for (int i = 0; i < Count; i++) { if (this[i].y <= point.y) { // start y <= P.y if (this[i + 1].y > point.y) // an upward crossing { if (PGUtils.LocatePointOnLine(this[i], this[i + 1], point) > 0) // P left of edge { ++wn; // have a valid up intersect } } } else { // start y > P.y (no test needed) if (this[i + 1].y <= point.y) // a downward crossing { if (PGUtils.LocatePointOnLine(this[i], this[i + 1], point) < 0) // P right of edge { --wn; // have a valid down intersect } } } } return(wn != 0); }
public static void InvertTriangles(this Mesh mesh) { for (int i = 0; i < mesh.subMeshCount; i++) { var triangles = mesh.GetTriangles(i); for (int j = 0; j < triangles.Length; j += 3) { PGUtils.Swap(ref triangles[j], ref triangles[j + 1]); } mesh.SetTriangles(triangles, i); } }
private static void WuLine(int x0, int y0, int x1, int y1, Action <int, int, float> draw) { bool steep = Math.Abs(y1 - y0) > Math.Abs(x1 - x0); if (steep) { PGUtils.Swap(ref x0, ref y0); PGUtils.Swap(ref x1, ref y1); } if (x0 > x1) { PGUtils.Swap(ref x0, ref x1); PGUtils.Swap(ref y0, ref y1); } if (steep) { draw(y0, x0, 1); draw(y1, x1, 1); } else { draw(x0, y0, 1); draw(x1, y1, 1); } float dx = x1 - x0; float dy = y1 - y0; float gradient = dy / dx; float y = y0 + gradient; for (var x = x0 + 1; x <= x1 - 1; x++) { if (steep) { draw((int)y, x, 1 - (y - (int)y)); draw((int)y + 1, x, y - (int)y); } else { draw(x, (int)y, 1 - (y - (int)y)); draw(x, (int)y + 1, y - (int)y); } y += gradient; } }
public static Polygon RemoveCollinearVertices(Polygon polygon) { if (polygon.Count <= 3) { return(polygon); } var newPolygon = new Polygon(); for (int i = 0; i < polygon.Count; i++) { if (PGUtils.LocatePointOnLine(polygon[i - 1], polygon[i + 1], polygon[i]) != 0) { newPolygon.Add(polygon[i]); } } return(newPolygon); }
public void ExtrudeRange(int startIndex, int endIndex, Vertex2 offset) { if (startIndex > endIndex) { PGUtils.Swap(ref startIndex, ref endIndex); } var startV = this[startIndex] + offset; var endV = this[endIndex] + offset; if ((endIndex - startIndex) > 1) { for (int i = startIndex + 1; i < endIndex; i++) { this[i] += offset; } } Insert(startIndex + 1, startV); Insert(endIndex + 1, endV); }
public void Swap() { PGUtils.Swap(ref x, ref y); }
/// <summary> /// Based on "Faster Line Segment Intersection" by Franklin Antonio, Graphics Gems III /// </summary> public static IntersectionType IntSegmentToIntSegmentE(int start0x, int start0y, int end0x, int end0y, int start1x, int start1y, int end1x, int end1y, out IntSegment2 intersection, bool testBoundingBox = false) { intersection = new IntSegment2(); int ax = end0x - start0x; int ay = end0y - start0y; int bx = start1x - end1x; int by = start1y - end1y; if (testBoundingBox) { // X bound box test int x1hi = end0x; int x1lo = start0x; if (ax < 0) { x1lo = end0x; x1hi = start0x; } if (bx > 0) { if (x1hi < end1x || start1x < x1lo) { return(IntersectionType.None); } } else { if (x1hi < start1x || end1x < x1lo) { return(IntersectionType.None); } } // Y bound box test int y1hi = end0y; int y1lo = start0y; if (ay < 0) { y1lo = end0y; y1hi = start0y; } if (by > 0) { if (y1hi < end1y || start1y < y1lo) { return(IntersectionType.None); } } else { if (y1hi < start1y || end1y < y1lo) { return(IntersectionType.None); } } } int cx = start0x - start1x; int cy = start0y - start1y; int denominator = ay * bx - ax * by; // Both denominator // Alpha tests int alphaNumerator = by * cx - bx * cy; if (denominator > 0) { if (alphaNumerator < 0 || alphaNumerator > denominator) { return(IntersectionType.None); } } else { if (alphaNumerator > 0 || alphaNumerator < denominator) { return(IntersectionType.None); } } // Beta tests int betaNumerator = ax * cy - ay * cx; if (denominator > 0) { if (betaNumerator < 0 || betaNumerator > denominator) { return(IntersectionType.None); } } else { if (betaNumerator > 0 || betaNumerator < denominator) { return(IntersectionType.None); } } // Compute intersection coordinates // Segments are parallel if (denominator == 0) { // Segments are noncollinear if (alphaNumerator != 0) { return(IntersectionType.None); } // Make sure that start is before end on x axis if (start0x > end0x) { PGUtils.Swap(ref start0x, ref end0x); PGUtils.Swap(ref start0y, ref end0y); } if (start1x > end1x) { PGUtils.Swap(ref start1x, ref end1x); PGUtils.Swap(ref start1y, ref end1y); } int biggestStartX = start0x > start1x ? start0x : start1x; int smallestEndX = end0x < end1x ? end0x : end1x; // Segments are collinear but not intersecting if (biggestStartX > smallestEndX) { return(IntersectionType.None); } // Make sure that start is before end on y axis // Remember swap event to prevent mirroring of intersection segment later bool swappedY = false; if (start0y > end0y) { PGUtils.Swap(ref start0x, ref end0x); PGUtils.Swap(ref start0y, ref end0y); swappedY = true; } if (start1y > end1y) { PGUtils.Swap(ref start1x, ref end1x); PGUtils.Swap(ref start1y, ref end1y); swappedY = true; } int biggestStartY = start0y > start1y ? start0y : start1y; int smallestEndY = end0y < end1y ? end0y : end1y; // Segments are collinear but not intersecting if (biggestStartY > smallestEndY) { return(IntersectionType.None); } if (swappedY) { intersection = new IntSegment2(biggestStartX, smallestEndY, smallestEndX, biggestStartY); } else { intersection = new IntSegment2(biggestStartX, biggestStartY, smallestEndX, smallestEndY); } return(IntersectionType.Segment); } int numerator = alphaNumerator * ax; // Numerator int x = start0x + numerator / denominator; // Intersection x numerator = alphaNumerator * ay; int y = start0y + numerator / denominator; // Intersection y intersection = new IntSegment2(x, y, x, y); return(IntersectionType.Point); }