/** * Monotone Chain algorithm. See * http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain */ static xyYPoint[] findConvexHull(xyYPoint[] points) { int n = points.Length, k = 0; xyYPoint[] tmpHull = new xyYPoint[2 * n]; Array.Sort(points, new xyYPointComparer()); // Build lower hull for (int i = 0; i < n; i++) { while (k >= 2 && cross(tmpHull[k - 2], tmpHull[k - 1], points[i]) <= 0) { k--; } tmpHull[k++] = points[i]; } // Build upper hull for (int i = n - 2, t = k + 1; i >= 0; i--) { while (k >= t && cross(tmpHull[k - 2], tmpHull[k - 1], points[i]) <= 0) { k--; } tmpHull[k++] = points[i]; } tmpHull [k - 1].x = -1000.0; // remove repetition return(tmpHull); }
/** * Computes the 'sharkin' points. */ static void computeSharkfin(IList <double> mfX, IList <double> mfY, IList <double> mfZ, ref xyYPoint[] Sharkfin, ref xyYPoint[] SortedSharkfin) { var n = mfX.Count; Sharkfin = new xyYPoint[n]; for (int i = 0; i < n; i++) { var XYZ = mfX [i] + mfY [i] + mfZ [i]; if (Math.Abs(XYZ) < double.Epsilon) { Sharkfin [i] = new xyYPoint { x = 0.0, y = 0.0 }; } else { Sharkfin [i] = new xyYPoint { x = mfX [i] / XYZ, y = mfY [i] / XYZ }; } } // Used to speedup the convex hull algorithm SortedSharkfin = (xyYPoint[])Sharkfin.Clone(); Array.Sort(SortedSharkfin, new xyYPointComparer()); }
/** * <inheritdoc /> */ public override bool IsInsideColorSpace(bool highPrecision = false) { // Fast checks if (y > 1.0 - x || y < (x - 0.25) * 0.5 || y < 0.4 - x * 4 || y >= 0.85) { return(false); } xyYPoint[] points; if (highPrecision) { points = new xyYPoint[SortedSharkfin1Nm.Length + 1]; Array.Copy(SortedSharkfin1Nm, 0, points, 0, SortedSharkfin1Nm.Length); points [SortedSharkfin1Nm.Length] = new xyYPoint { x = x, y = y }; } else { points = new xyYPoint[SortedSharkfin5Nm.Length + 1]; Array.Copy(SortedSharkfin5Nm, 0, points, 0, SortedSharkfin5Nm.Length); points [SortedSharkfin5Nm.Length] = new xyYPoint { x = x, y = y }; } xyYPoint[] convexHull = findConvexHull(points); for (int i = 0; i < convexHull.Length; i++) { if (convexHull [i].x == x && convexHull [i].y == y) { return(false); } } return(true); }
/** * Used inside findConvexHull method. */ static double cross(xyYPoint O, xyYPoint A, xyYPoint B) { return (A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x); }
/** * Monotone Chain algorithm. See * http://en.wikibooks.org/wiki/Algorithm_Implementation/Geometry/Convex_hull/Monotone_chain */ static xyYPoint[] findConvexHull(xyYPoint[] points) { int n = points.Length, k = 0; xyYPoint[] tmpHull = new xyYPoint[2 * n]; Array.Sort (points, new xyYPointComparer ()); // Build lower hull for (int i = 0; i < n; i++) { while (k >= 2 && cross(tmpHull[k - 2], tmpHull[k - 1], points[i]) <= 0) k--; tmpHull[k++] = points[i]; } // Build upper hull for (int i = n - 2, t = k + 1; i >= 0; i--) { while (k >= t && cross(tmpHull[k - 2], tmpHull[k - 1], points[i]) <= 0) k--; tmpHull[k++] = points[i]; } tmpHull [k - 1].x = -1000.0; // remove repetition return tmpHull; }
/** * <inheritdoc /> */ public override bool IsInsideColorSpace(bool highPrecision = false) { // Fast checks if (y > 1.0 - x || y < (x - 0.25) * 0.5 || y < 0.4 - x * 4 || y >= 0.85) return false; xyYPoint[] points; if (highPrecision) { points = new xyYPoint[SortedSharkfin1Nm.Length + 1]; Array.Copy (SortedSharkfin1Nm, 0, points, 0, SortedSharkfin1Nm.Length); points [SortedSharkfin1Nm.Length] = new xyYPoint{ x = x, y = y }; } else { points = new xyYPoint[SortedSharkfin5Nm.Length + 1]; Array.Copy (SortedSharkfin5Nm, 0, points, 0, SortedSharkfin5Nm.Length); points [SortedSharkfin5Nm.Length] = new xyYPoint{ x = x, y = y }; } xyYPoint[] convexHull = findConvexHull (points); for (int i = 0; i < convexHull.Length; i++) { if (convexHull [i].x == x && convexHull [i].y == y) return false; } return true; }
/** * Computes the 'sharkin' points. */ static void computeSharkfin(IList<double> mfX, IList<double> mfY, IList<double> mfZ, ref xyYPoint[] Sharkfin, ref xyYPoint[] SortedSharkfin) { var n = mfX.Count; Sharkfin = new xyYPoint[n]; for (int i = 0; i < n; i++) { var XYZ = mfX [i] + mfY [i] + mfZ [i]; if (Math.Abs (XYZ) < double.Epsilon) { Sharkfin [i] = new xyYPoint { x = 0.0, y = 0.0 }; } else { Sharkfin [i] = new xyYPoint { x = mfX [i] / XYZ, y = mfY [i] / XYZ }; } } // Used to speedup the convex hull algorithm SortedSharkfin = (xyYPoint[])Sharkfin.Clone(); Array.Sort (SortedSharkfin, new xyYPointComparer()); }
/** * Used inside findConvexHull method. */ static double cross(xyYPoint O, xyYPoint A, xyYPoint B) { return((A.x - O.x) * (B.y - O.y) - (A.y - O.y) * (B.x - O.x)); }