Skip to content

Add Jarvis March in C#. #85

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
May 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Public fields should be Pascal case

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<Vector> Run(List<Vector> points)
{
var convexHull = new List<Vector>();

// 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);
}
}
Original file line number Diff line number Diff line change
@@ -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<Vector>()
{
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}");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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)
Expand Down Expand Up @@ -57,4 +62,3 @@ $$
\newcommand{\bfomega}{\boldsymbol{\omega}}
\newcommand{\bftau}{\boldsymbol{\tau}}
$$