Skip to content

Commit d27b044

Browse files
june128leios
authored andcommitted
Add Jarvis March in C#. (#85)
* Add Jarvis March in C#. * Make JarvisMarch non-static. Simplify RunJarvisMarch's name to Run. Add ScalarProduct to Vector. * Make Vector a struct and make fields readonly. Overload operator for Vector. Add mention for gustorn's help. * Refactor and simplify code. Update mention. Resolve compiler warnings. * Fix mention. * Simplify code. Improve comments. Remove redundant operators.
1 parent 974a005 commit d27b044

File tree

3 files changed

+97
-2
lines changed

3 files changed

+97
-2
lines changed
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
// submitted by Julian Schacher (jspp) with great help by gustorn
2+
using System;
3+
using System.Collections.Generic;
4+
using System.Linq;
5+
6+
namespace JarvisMarch
7+
{
8+
public struct Vector
9+
{
10+
public readonly int x;
11+
public readonly int y;
12+
13+
public Vector(int xValue, int yValue)
14+
{
15+
this.x = xValue;
16+
this.y = yValue;
17+
}
18+
19+
public override bool Equals(object obj) => obj is Vector v && this.x == v.x && this.y == v.y;
20+
public override int GetHashCode() => (17 * 23 + this.x) * 23 + this.y;
21+
22+
public static bool operator==(Vector a, Vector b) => a.Equals(b);
23+
public static bool operator!=(Vector a, Vector b) => !(a == b);
24+
}
25+
26+
public class JarvisMarch
27+
{
28+
public List<Vector> Run(List<Vector> points)
29+
{
30+
var convexHull = new List<Vector>();
31+
32+
// Set the intial pointOnHull to the point of the list, where the x-position is the lowest.
33+
var pointOnHull = points.Aggregate((leftmost, current) => leftmost.x < current.x ? leftmost : current);
34+
35+
// Continue searching for the next pointOnHull until the next pointOnHull is equal to the first point of the convex hull.
36+
do
37+
{
38+
convexHull.Add(pointOnHull);
39+
40+
// Search for the next pointOnHull by looking which of the points is the next most outer point.
41+
pointOnHull = points.Aggregate((potentialNextPointOnHull, current) =>
42+
{
43+
// 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.
44+
if (potentialNextPointOnHull == pointOnHull || IsLeftOf(pointOnHull, potentialNextPointOnHull, current))
45+
return current;
46+
return potentialNextPointOnHull;
47+
});
48+
49+
// Check if the gift wrap is completed.
50+
} while (pointOnHull != convexHull[0]);
51+
52+
return convexHull;
53+
}
54+
55+
// Returns true, if p is left of the line defined by a and b.
56+
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);
57+
}
58+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
// submitted by Julian Schacher (jspp) with great help by gustorn
2+
using System;
3+
using System.Collections.Generic;
4+
5+
namespace JarvisMarch
6+
{
7+
class Program
8+
{
9+
static void Main(string[] args)
10+
{
11+
System.Console.WriteLine("JarvisMarch");
12+
// Example list of points.
13+
// The points are represented by vectors here, but that doesn't really matter.
14+
var points = new List<Vector>()
15+
{
16+
new Vector(1, 3),
17+
new Vector(2, 4),
18+
new Vector(4, 0),
19+
new Vector(1, 0),
20+
new Vector(0, 2),
21+
new Vector(2, 2),
22+
new Vector(3, 4),
23+
new Vector(3, 1),
24+
};
25+
var jarvisMarch = new JarvisMarch();
26+
var giftWrap = jarvisMarch.Run(points);
27+
28+
// Print the points of the gift wrap.
29+
foreach (var point in giftWrap)
30+
System.Console.WriteLine($"{point.x}, {point.y}");
31+
}
32+
}
33+
}

chapters/computational_geometry/gift_wrapping/jarvis_march/jarvis_march.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ From there, we use the two known points to again calculate the angle between all
1111
We then choose the point with the largest interior angle and move the simulation forward.
1212
We keep repeating this process until we have returned to our original point.
1313
The set of points chosen in this simulation will be the convex hull.
14-
Here is what this might look like in code:
1514

1615
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.
1716
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
2423
### Example Code
2524

2625
{% method %}
26+
{% sample lang="cs" %}
27+
### C# #
28+
JarvisMarch.cs
29+
[import, lang="csharp"](code/cs/JarvisMarch.cs)
30+
Program.cs
31+
[import, lang="csharp"](code/cs/Program.cs)
2732
{% sample lang="jl" %}
2833
### Julia
2934
[import, lang:"julia"](code/julia/jarvis.jl)
@@ -57,4 +62,3 @@ $$
5762
\newcommand{\bfomega}{\boldsymbol{\omega}}
5863
\newcommand{\bftau}{\boldsymbol{\tau}}
5964
$$
60-

0 commit comments

Comments
 (0)