restructure; add challenge 2 solution

I forgot about atomic commits...
This commit is contained in:
raf 2024-12-01 17:09:14 +03:00
commit bfb7d95aa7
Signed by: NotAShelf
GPG key ID: AF26552424E53993
10 changed files with 207 additions and 64 deletions

4
lib/geometry/Cargo.toml Normal file
View file

@ -0,0 +1,4 @@
[package]
name = "geometry"
version = "0.1.0"
edition = "2021"

101
lib/geometry/src/lib.rs Normal file
View file

@ -0,0 +1,101 @@
use std::io;
// 'Point' struct represents a 2D point
// with X and Y coordinates.
#[derive(Debug, Clone)]
pub struct Point {
pub x: f64,
pub y: f64,
}
// This is a triangle.
// No seriously, it is.
#[derive(Debug, Clone)]
pub struct Triangle {
pub p1: Point,
pub p2: Point,
pub p3: Point,
}
impl Triangle {
// Calculate the area of the triangle
fn area(&self) -> f64 {
((self.p1.x * (self.p2.y - self.p3.y)
+ self.p2.x * (self.p3.y - self.p1.y)
+ self.p3.x * (self.p1.y - self.p2.y))
/ 2.0)
.abs()
}
// Check if a given point lies within the triangle
pub fn contains_point(&self, point: &Point) -> bool {
let area_total = self.area();
let area1 = Triangle {
p1: point.clone(),
p2: self.p2.clone(),
p3: self.p3.clone(),
}
.area();
let area2 = Triangle {
p1: self.p1.clone(),
p2: point.clone(),
p3: self.p3.clone(),
}
.area();
let area3 = Triangle {
p1: self.p1.clone(),
p2: self.p2.clone(),
p3: point.clone(),
}
.area();
// Check if the sum of sub-areas equals the total area
// There is a small treshold of tolerance.
(area1 + area2 + area3 - area_total).abs() < 1e-9
}
// Check if a given triangle overlaps with another
// and return true if it does.
pub fn overlaps(&self, other: &Triangle) -> bool {
// if any point of `self` lies inside `other`
let self_points = [&self.p1, &self.p2, &self.p3];
for point in self_points {
if other.contains_point(point) {
return true;
}
}
// if any point of `other` lies inside `self`
let other_points = [&other.p1, &other.p2, &other.p3];
for point in other_points {
if self.contains_point(point) {
return true;
}
}
// No overlap :(
false
}
}
// Read a point from user input
// This should be generic enough to reuse.
pub fn read_point(prompt: &str) -> Point {
println!("{}", prompt);
let mut input = String::new();
io::stdin().read_line(&mut input).unwrap();
let coords: Vec<f64> = input
.trim()
.split_whitespace()
.filter_map(|x| x.parse::<f64>().ok())
.collect();
if coords.len() != 2 {
panic!("Invalid input: expected two numbers for the point coordinates");
}
Point {
x: coords[0],
y: coords[1],
}
}