aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorArne Dußin2020-11-21 20:55:47 +0100
committerArne Dußin2020-11-21 20:55:47 +0100
commitabf55d8d46fc7d5cfccc9f778da6fca10b33d0cd (patch)
treee2f849338a1ce9dfff44082fa7d6b8510385f6f9 /src
parent58ca374fab6dd90c4d7415bdcc98add002274894 (diff)
downloadgraf_karto-abf55d8d46fc7d5cfccc9f778da6fca10b33d0cd.tar.gz
graf_karto-abf55d8d46fc7d5cfccc9f778da6fca10b33d0cd.zip
Move containment of points/ lines into trait
Diffstat (limited to 'src')
-rw-r--r--src/gui/tool_sidebar.rs4
-rw-r--r--src/math/line_segment.rs6
-rw-r--r--src/math/mod.rs10
-rw-r--r--src/math/polygon/mod.rs53
-rw-r--r--src/math/rect.rs112
-rw-r--r--src/tool/deletion_tool.rs6
6 files changed, 105 insertions, 86 deletions
diff --git a/src/gui/tool_sidebar.rs b/src/gui/tool_sidebar.rs
index 46b53ea..7674c47 100644
--- a/src/gui/tool_sidebar.rs
+++ b/src/gui/tool_sidebar.rs
@@ -1,4 +1,4 @@
-use crate::math::{Rect, Vec2};
+use crate::math::{Rect, Surface, Vec2};
use crate::tool::ToolType;
use crate::Editor;
use raylib::core::texture::Texture2D;
@@ -28,7 +28,7 @@ impl ToolSidebar {
/// Check if the mouse is currently being captured by this GUI-element. In that case,
/// everything else that might want to access the mouse will be blocked.
pub fn mouse_captured(screen_height: u16, mouse_pos: Vec2<f32>) -> bool {
- Self::panel_rect(screen_height).contains(mouse_pos)
+ Self::panel_rect(screen_height).contains_point(&mouse_pos)
}
pub fn draw(&self, screen_height: u16, rld: &mut impl RaylibDrawGui, editor: &mut Editor) {
diff --git a/src/math/line_segment.rs b/src/math/line_segment.rs
index 244b0af..94f58b2 100644
--- a/src/math/line_segment.rs
+++ b/src/math/line_segment.rs
@@ -1,4 +1,4 @@
-use super::{Rect, TripletOrientation, Vec2};
+use super::{Rect, Surface, TripletOrientation, Vec2};
use alga::general::{ClosedDiv, ClosedMul, ClosedSub};
use nalgebra::{RealField, Scalar};
use num_traits::Zero;
@@ -118,8 +118,8 @@ impl<T: Scalar + Copy> LineSegment<T> {
* the segments. We know it's on the lines, so checking with the lines bounding box is
* faster than checking where on the line exactly it would be.
*/
- if Rect::bounding_rect(line_a.start, line_a.end).contains(out)
- && Rect::bounding_rect(line_b.start, line_b.end).contains(out)
+ if Rect::bounding_rect(line_a.start, line_a.end).contains_point(&out)
+ && Rect::bounding_rect(line_b.start, line_b.end).contains_point(&out)
{
Some(out)
} else {
diff --git a/src/math/mod.rs b/src/math/mod.rs
index e72a7a4..6f83c98 100644
--- a/src/math/mod.rs
+++ b/src/math/mod.rs
@@ -10,8 +10,18 @@ pub use self::rect::*;
pub use self::triangle::*;
pub use self::vec2::*;
+use nalgebra::Scalar;
use std::cmp::Ordering;
+/// Trait that describes an area in the vector space on the field of T
+pub trait Surface<T: Scalar + Copy> {
+ /// Checks if a point lies on this surface.
+ fn contains_point(&self, point: &Vec2<T>) -> bool;
+
+ /// Checks if a line segment is entirely contained by this surface.
+ fn contains_line_segment(&self, line_segment: &LineSegment<T>) -> bool;
+}
+
/// Round a floating point number to the nearest step given by the step argument. For instance, if
/// the step is 0.5, then all numbers from 0.0 to 0.24999... will be 0., while all numbers from
/// 0.25 to 0.74999... will be 0.5 and so on.
diff --git a/src/math/polygon/mod.rs b/src/math/polygon/mod.rs
index 4530857..d351ec7 100644
--- a/src/math/polygon/mod.rs
+++ b/src/math/polygon/mod.rs
@@ -6,7 +6,7 @@ pub mod triangulate;
pub use polygon_graph::*;
pub use triangulate::*;
-use super::Vec2;
+use super::{LineSegment, Surface, Vec2};
use nalgebra::{ClosedDiv, ClosedMul, ClosedSub, RealField, Scalar};
use num_traits::Zero;
use std::ops::Neg;
@@ -24,10 +24,27 @@ impl<T: Scalar + Copy> Polygon<T> {
/// Check whether a point is inside a polygon or not. If a point lies on an edge, it also
/// counts as inside the polygon.
- pub fn contains_point(&self, p: Vec2<T>) -> bool
+
+ /// Join this polygon with another, ensuring the area of the two stays the same, but the
+ /// overlap is not doubled, but instead joined into one.
+ /// Returns the Polygons themselves, if there is no overlap
+ pub fn unite(self, other: Polygon<T>) -> Vec<Polygon<T>>
where
- T: Zero + ClosedSub + ClosedMul + ClosedDiv + Neg<Output = T> + PartialOrd,
+ T: RealField,
{
+ let mut graph = PolygonGraph::from_polygon(&self);
+ graph.add_all(&other);
+
+ // TODO: Make bounding box support multiple polygons
+ vec![graph.bounding_polygon()]
+ }
+}
+
+impl<
+ T: Scalar + Copy + ClosedSub + ClosedMul + ClosedDiv + Neg<Output = T> + PartialOrd + Zero,
+ > Surface<T> for Polygon<T>
+{
+ fn contains_point(&self, p: &Vec2<T>) -> bool {
let n = self.corners.len();
let a = self.corners[n - 1];
@@ -102,18 +119,8 @@ impl<T: Scalar + Copy> Polygon<T> {
(depth & 1) == 1
}
- /// Join this polygon with another, ensuring the area of the two stays the same, but the
- /// overlap is not doubled, but instead joined into one.
- /// Returns the Polygons themselves, if there is no overlap
- pub fn unite(self, other: Polygon<T>) -> Vec<Polygon<T>>
- where
- T: RealField,
- {
- let mut graph = PolygonGraph::from_polygon(&self);
- graph.add_all(&other);
-
- // TODO: Make bounding box support multiple polygons
- vec![graph.bounding_polygon()]
+ fn contains_line_segment(&self, line_segment: &LineSegment<T>) -> bool {
+ unimplemented!()
}
}
@@ -133,14 +140,14 @@ mod test {
Vec2::new(1., 1.),
]);
- assert!(!polygon.contains_point(Vec2::new(1., -2.)));
- assert!(!polygon.contains_point(Vec2::new(-1., 0.5)));
- assert!(polygon.contains_point(Vec2::new(0., 0.5)));
- assert!(polygon.contains_point(Vec2::new(0.5, 1.)));
- assert!(polygon.contains_point(Vec2::new(0.5, 1.5)));
- assert!(!polygon.contains_point(Vec2::new(-2., 1.9)));
- assert!(!polygon.contains_point(Vec2::new(0., 3.)));
- assert!(polygon.contains_point(Vec2::new(1., 3.)));
+ assert!(!polygon.contains_point(&Vec2::new(1., -2.)));
+ assert!(!polygon.contains_point(&Vec2::new(-1., 0.5)));
+ assert!(polygon.contains_point(&Vec2::new(0., 0.5)));
+ assert!(polygon.contains_point(&Vec2::new(0.5, 1.)));
+ assert!(polygon.contains_point(&Vec2::new(0.5, 1.5)));
+ assert!(!polygon.contains_point(&Vec2::new(-2., 1.9)));
+ assert!(!polygon.contains_point(&Vec2::new(0., 3.)));
+ assert!(polygon.contains_point(&Vec2::new(1., 3.)));
}
#[test]
diff --git a/src/math/rect.rs b/src/math/rect.rs
index 6988b2c..876e728 100644
--- a/src/math/rect.rs
+++ b/src/math/rect.rs
@@ -1,6 +1,6 @@
-use super::Vec2;
+use super::{LineSegment, Surface, Vec2};
//use alga::general::{Additive, Identity};
-use nalgebra::{RealField, Scalar};
+use nalgebra::{ClosedAdd, RealField, Scalar};
use num_traits::identities::Zero;
use serde::{Deserialize, Serialize};
use std::ops::{Add, AddAssign, Sub};
@@ -18,48 +18,6 @@ pub struct Rect<T: Scalar + Copy> {
pub h: T,
}
-// This is sad, but also sadly necessary :/
-impl<T: Into<f32> + Scalar + Copy> Into<raylib::ffi::Rectangle> for Rect<T> {
- fn into(self) -> raylib::ffi::Rectangle {
- raylib::ffi::Rectangle {
- x: self.x.into(),
- y: self.y.into(),
- width: self.w.into(),
- height: self.h.into(),
- }
- }
-}
-impl<T: From<f32> + Scalar + Copy> From<raylib::ffi::Rectangle> for Rect<T> {
- fn from(r: raylib::ffi::Rectangle) -> Self {
- Self {
- x: T::from(r.x),
- y: T::from(r.y),
- w: T::from(r.width),
- h: T::from(r.height),
- }
- }
-}
-impl<T: Into<f32> + Scalar + Copy> Into<raylib::math::Rectangle> for Rect<T> {
- fn into(self) -> raylib::math::Rectangle {
- raylib::math::Rectangle {
- x: self.x.into(),
- y: self.y.into(),
- width: self.w.into(),
- height: self.h.into(),
- }
- }
-}
-impl<T: From<f32> + Scalar + Copy> From<raylib::math::Rectangle> for Rect<T> {
- fn from(r: raylib::math::Rectangle) -> Self {
- Self {
- x: T::from(r.x),
- y: T::from(r.y),
- w: T::from(r.width),
- h: T::from(r.height),
- }
- }
-}
-
impl<T: Scalar + Copy> Rect<T> {
pub fn new(x: T, y: T, w: T, h: T) -> Self {
Self { x, y, w, h }
@@ -105,17 +63,6 @@ impl<T: Scalar + Copy> Rect<T> {
|| this.y + this.h < other.y)
}
- /// Check if the point is inside this Rect and return true if so.
- pub fn contains(&self, point: Vec2<T>) -> bool
- where
- T: PartialOrd + Add<Output = T>,
- {
- point.x >= self.x
- && point.x <= self.x + self.w
- && point.y >= self.y
- && point.y <= self.y + self.h
- }
-
/// Returns true if the entire rect is contained inside this rectangle.
pub fn contains_rect(&self, rect: Rect<T>) -> bool
where
@@ -181,6 +128,61 @@ impl<T: Scalar + Copy> Rect<T> {
}
}
+impl<T: Scalar + Copy + PartialOrd + ClosedAdd> Surface<T> for Rect<T> {
+ fn contains_point(&self, point: &Vec2<T>) -> bool {
+ point.x >= self.x
+ && point.x <= self.x + self.w
+ && point.y >= self.y
+ && point.y <= self.y + self.h
+ }
+
+ fn contains_line_segment(&self, line_segment: &LineSegment<T>) -> bool {
+ self.contains_point(&line_segment.start) && self.contains_point(&line_segment.end)
+ }
+}
+
+// This is sad, but also sadly necessary :/
+impl<T: Into<f32> + Scalar + Copy> Into<raylib::ffi::Rectangle> for Rect<T> {
+ fn into(self) -> raylib::ffi::Rectangle {
+ raylib::ffi::Rectangle {
+ x: self.x.into(),
+ y: self.y.into(),
+ width: self.w.into(),
+ height: self.h.into(),
+ }
+ }
+}
+impl<T: From<f32> + Scalar + Copy> From<raylib::ffi::Rectangle> for Rect<T> {
+ fn from(r: raylib::ffi::Rectangle) -> Self {
+ Self {
+ x: T::from(r.x),
+ y: T::from(r.y),
+ w: T::from(r.width),
+ h: T::from(r.height),
+ }
+ }
+}
+impl<T: Into<f32> + Scalar + Copy> Into<raylib::math::Rectangle> for Rect<T> {
+ fn into(self) -> raylib::math::Rectangle {
+ raylib::math::Rectangle {
+ x: self.x.into(),
+ y: self.y.into(),
+ width: self.w.into(),
+ height: self.h.into(),
+ }
+ }
+}
+impl<T: From<f32> + Scalar + Copy> From<raylib::math::Rectangle> for Rect<T> {
+ fn from(r: raylib::math::Rectangle) -> Self {
+ Self {
+ x: T::from(r.x),
+ y: T::from(r.y),
+ w: T::from(r.width),
+ h: T::from(r.height),
+ }
+ }
+}
+
#[cfg(test)]
mod test {
use super::*;
diff --git a/src/tool/deletion_tool.rs b/src/tool/deletion_tool.rs
index c313574..5031f5d 100644
--- a/src/tool/deletion_tool.rs
+++ b/src/tool/deletion_tool.rs
@@ -2,7 +2,7 @@ use super::Tool;
use crate::button::Button;
use crate::config::{DeletionToolKeybindings, ToolKeybindings};
use crate::map_data::MapData;
-use crate::math::{Rect, Vec2};
+use crate::math::{Rect, Surface, Vec2};
use crate::transform::Transform;
use raylib::core::drawing::{RaylibDraw, RaylibDrawHandle};
use raylib::ffi::Color;
@@ -28,10 +28,10 @@ impl DeletionTool {
.retain(|&room| !rect.contains_rect(room));
map_data
.walls_mut()
- .retain(|&(pos1, pos2)| !rect.contains(pos1) || !rect.contains(pos2));
+ .retain(|&(pos1, pos2)| !rect.contains_point(&pos1) || !rect.contains_point(&pos2));
map_data
.icons_mut()
- .retain(|icon| !rect.contains(icon.position));
+ .retain(|icon| !rect.contains_point(&icon.position));
}
}