diff --git a/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/JarvisMarch.cs b/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/JarvisMarch.cs new file mode 100644 index 000000000..62b92bc65 --- /dev/null +++ b/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/JarvisMarch.cs @@ -0,0 +1,58 @@ +// submitted by Julian Schacher (jspp) with great help by gustorn +using System; +using System.Collections.Generic; +using System.Linq; + +namespace JarvisMarch +{ + public struct Vector + { + public readonly int x; + public readonly int y; + + public Vector(int xValue, int yValue) + { + this.x = xValue; + this.y = yValue; + } + + public override bool Equals(object obj) => obj is Vector v && this.x == v.x && this.y == v.y; + public override int GetHashCode() => (17 * 23 + this.x) * 23 + this.y; + + public static bool operator==(Vector a, Vector b) => a.Equals(b); + public static bool operator!=(Vector a, Vector b) => !(a == b); + } + + public class JarvisMarch + { + public List Run(List points) + { + var convexHull = new List(); + + // Set the intial pointOnHull to the point of the list, where the x-position is the lowest. + var pointOnHull = points.Aggregate((leftmost, current) => leftmost.x < current.x ? leftmost : current); + + // Continue searching for the next pointOnHull until the next pointOnHull is equal to the first point of the convex hull. + do + { + convexHull.Add(pointOnHull); + + // Search for the next pointOnHull by looking which of the points is the next most outer point. + pointOnHull = points.Aggregate((potentialNextPointOnHull, current) => + { + // Returns true, if potentialNextPointOnHull is equal to the current pointOnHull or if the current point is left of the line defined by pointOnHull and potentialNextPointOnHull. + if (potentialNextPointOnHull == pointOnHull || IsLeftOf(pointOnHull, potentialNextPointOnHull, current)) + return current; + return potentialNextPointOnHull; + }); + + // Check if the gift wrap is completed. + } while (pointOnHull != convexHull[0]); + + return convexHull; + } + + // Returns true, if p is left of the line defined by a and b. + private bool IsLeftOf(Vector a, Vector b, Vector p) => (b.x - a.x) * (p.y - a.y) > (p.x - a.x) * (b.y - a.y); + } +} diff --git a/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/Program.cs b/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/Program.cs new file mode 100644 index 000000000..d927b62bf --- /dev/null +++ b/chapters/computational_geometry/gift_wrapping/jarvis_march/code/cs/Program.cs @@ -0,0 +1,33 @@ +// submitted by Julian Schacher (jspp) with great help by gustorn +using System; +using System.Collections.Generic; + +namespace JarvisMarch +{ + class Program + { + static void Main(string[] args) + { + System.Console.WriteLine("JarvisMarch"); + // Example list of points. + // The points are represented by vectors here, but that doesn't really matter. + var points = new List() + { + new Vector(1, 3), + new Vector(2, 4), + new Vector(4, 0), + new Vector(1, 0), + new Vector(0, 2), + new Vector(2, 2), + new Vector(3, 4), + new Vector(3, 1), + }; + var jarvisMarch = new JarvisMarch(); + var giftWrap = jarvisMarch.Run(points); + + // Print the points of the gift wrap. + foreach (var point in giftWrap) + System.Console.WriteLine($"{point.x}, {point.y}"); + } + } +} diff --git a/chapters/computational_geometry/gift_wrapping/jarvis_march/jarvis_march.md b/chapters/computational_geometry/gift_wrapping/jarvis_march/jarvis_march.md index 09587d94b..82f902122 100644 --- a/chapters/computational_geometry/gift_wrapping/jarvis_march/jarvis_march.md +++ b/chapters/computational_geometry/gift_wrapping/jarvis_march/jarvis_march.md @@ -11,7 +11,6 @@ From there, we use the two known points to again calculate the angle between all We then choose the point with the largest interior angle and move the simulation forward. We keep repeating this process until we have returned to our original point. The set of points chosen in this simulation will be the convex hull. -Here is what this might look like in code: As we might expect, this algorithm is not incredibly efficient and has a runtime of $$\mathcal{O}(nh)$$, where $$n$$ is the number of points and $$h$$ is the size of the hull. As a note, the Jarvis March can be generalized to higher dimensions. @@ -24,6 +23,12 @@ Since this algorithm, there have been many other algorithms that have advanced t ### Example Code {% method %} +{% sample lang="cs" %} +### C# # +JarvisMarch.cs +[import, lang="csharp"](code/cs/JarvisMarch.cs) +Program.cs +[import, lang="csharp"](code/cs/Program.cs) {% sample lang="jl" %} ### Julia [import, lang:"julia"](code/julia/jarvis.jl) @@ -57,4 +62,3 @@ $$ \newcommand{\bfomega}{\boldsymbol{\omega}} \newcommand{\bftau}{\boldsymbol{\tau}} $$ -