-
-
Notifications
You must be signed in to change notification settings - Fork 359
Implement Graham Scan in Rust #964
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
ShadowMitia
merged 17 commits into
algorithm-archivists:main
from
PeanutbutterWarrior:graham-scan-rust
Jan 12, 2022
Merged
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
6437dc2
Implement Graham Scan in Rust
ThijsRay 83bc531
Add Thijs
PeanutbutterWarrior 5e92e7a
Remove compiled binary
PeanutbutterWarrior edf9759
Define ordering of points for sorting
PeanutbutterWarrior f8b773d
Clean up code
PeanutbutterWarrior e823152
Change points to match other implementations
PeanutbutterWarrior cb13797
Apply requested changes from #479
PeanutbutterWarrior 663a887
Fix function signature
PeanutbutterWarrior 66acb12
Merge branch 'main' into graham-scan-rust
PeanutbutterWarrior 3abbfa6
Merge branch 'main' into graham-scan-rust
Amaras 071a1c8
Add function comment
PeanutbutterWarrior fb17209
Change algorithm to simpler version from python
PeanutbutterWarrior 2876f03
Fix points to match other languages
PeanutbutterWarrior c1d7ec0
Adjust line numbers for rust
PeanutbutterWarrior 6451a93
Merge branch 'main' into graham-scan-rust
PeanutbutterWarrior 9e77b5d
Apply clippy suggestions
PeanutbutterWarrior 7ccd228
Merge branch 'main' into graham-scan-rust
ShadowMitia File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
use std::cmp::Ordering; | ||
|
||
#[derive(Debug, PartialEq, Copy, Clone)] | ||
struct Point { | ||
x: f64, | ||
y: f64, | ||
} | ||
|
||
impl Eq for Point {} | ||
|
||
impl PartialOrd for Point { | ||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||
if self.y == other.y { | ||
self.x.partial_cmp(&other.x) | ||
} else { | ||
self.y.partial_cmp(&other.y) | ||
} | ||
} | ||
} | ||
|
||
// Defines an order for Points so they can be sorted | ||
impl Ord for Point { | ||
fn cmp(&self, other: &Self) -> Ordering { | ||
// Neither field of Point will be NaN, so this is safe | ||
self.partial_cmp(other).unwrap() | ||
} | ||
} | ||
|
||
// Determines whether the angle abc is clockwise, counter-clockwise or colinear | ||
// result > 0 : counter-clockwise | ||
// result = 0 : colinear | ||
// result < 0 : clockwise | ||
fn counter_clockwise(a: &Point, b: &Point, c: &Point) -> f64 { | ||
(b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x) | ||
} | ||
|
||
// Calculate the polar angle of a point relative to a reference point. | ||
fn polar_angle(reference: &Point, point: &Point) -> f64 { | ||
(point.y - reference.y).atan2(point.x - reference.x) | ||
} | ||
|
||
fn graham_scan(mut points: Vec<Point>) -> Vec<Point> { | ||
if points.is_empty() { | ||
return Vec::new(); | ||
} | ||
|
||
// Unwrap is safe because length is > 0 | ||
let start = *points.iter().min().unwrap(); | ||
points.retain(|a| a != &start); | ||
points.sort_unstable_by(|a, b| polar_angle(&start, a).partial_cmp(&polar_angle(&start, b)).unwrap()); | ||
|
||
let mut hull: Vec<Point> = vec![start, points[0], points[1]]; | ||
|
||
for pt in points[2..points.len()].iter() { | ||
while counter_clockwise(&hull[hull.len() - 2], &hull[hull.len() - 1], pt) < 0.0 { | ||
hull.pop(); | ||
} | ||
hull.push(*pt); | ||
} | ||
hull | ||
} | ||
|
||
fn main() { | ||
let points = vec![ | ||
Point { x: -5.0, y: 2.0 }, | ||
Point { x: 5.0, y: 7.0 }, | ||
Point { x: -6.0, y: -12.0 }, | ||
Point { x: -14.0, y: -14.0 }, | ||
Point { x: 9.0, y: 9.0 }, | ||
Point { x: -1.0, y: -1.0 }, | ||
Point { x: -10.0, y: 11.0 }, | ||
Point { x: -6.0, y: 15.0 }, | ||
Point { x: -6.0, y: -8.0 }, | ||
Point { x: 15.0, y: -9.0 }, | ||
Point { x: 7.0, y: -7.0 }, | ||
Point { x: -2.0, y: -9.0 }, | ||
Point { x: 6.0, y: -5.0 }, | ||
Point { x: 0.0, y: 14.0 }, | ||
Point { x: 2.0, y: 8.0 }, | ||
]; | ||
|
||
let hull_points = graham_scan(points); | ||
println!("{:#?}", hull_points); | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.