Polygon2D

Struct Polygon2D 

Source
pub struct Polygon2D {
    pub vertices: Vec<Point2D>,
}
Expand description

Represents a two-dimensional closed polygon.

Polygon should contain at least 3 vertices, all vertices should be unique.

§Example

Here below is an example of defining polygon which represents a triangle shape, that’s why there are 3 vertices.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)];

let result = Polygon2D::new(input);

assert_eq!(result.vertices, vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

Fields§

§vertices: Vec<Point2D>

Vertices which define closed Polygon2D.

Implementations§

Source§

impl Polygon2D

Source

pub fn new(vertices: Vec<Point2D>) -> Polygon2D

Returns a new Polygon2D.

§Example
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)];

let result = Polygon2D::new(input);

assert_eq!(result.vertices, vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);
Source§

impl Polygon2D

Source

pub fn is_clockwise(&self) -> bool

Checks if given Polygon2D is clockwise.

If true is returned: it should be clockwise. If false: it should be counter-clockwise.

This method assumes normal cartesian coordinate system with the Y-axis pointing up.

§Examples

Here below there is an example of a clockwise Polygon2D, so true is expected.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0), Point2D::new(5.0, -10.0)]);

assert!(input.is_clockwise());

Here below there is an example of counter-clockwise Polygon2D, so false is expected.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, -10.0), Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0)]);

assert!(!input.is_clockwise());
Source

pub fn get_first_not_straight_vertex_id( &self, angle_tolerance: f64, ) -> Option<usize>

Tries to get the id of the very first vertex, which is actually concave or convex, not the straight one.

Every Polygon2D should have every vertex concave or convex, not straight, but sometimes not cleaned Polygon2Ds can happen, then such check could be useful.

If the None is returned, then there is no such vertex, which also means that this Polygon2D is not correct, and it is a some sort of the straight line.

§Example

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(54.5, 25.0),
    Point2D::new(53.5, 25.0),
    Point2D::new(52.5, 25.0),
    Point2D::new(50.0, 25.0), // This one is first one not straight, so 3 should be returned
    Point2D::new(50.0, 50.0),
    Point2D::new(65.0, 50.0),
    Point2D::new(65.0, 45.0),
    Point2D::new(55.0, 45.0),
    Point2D::new(55.0, 40.0),
    Point2D::new(65.0, 40.0),
    Point2D::new(65.0, 35.0),
    Point2D::new(55.0, 35.0),
    Point2D::new(55.0, 25.0),
]);
 
let actual = input.get_first_not_straight_vertex_id(0.01745);
 
assert_eq!(Some(3), actual);
Source

pub fn get_bounding_area(&self) -> BoundingArea

Calculates the BoundingArea for this Polygon2D.

§Example
use meshmeshmesh::bounding_area::BoundingArea;
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

let actual = input.get_bounding_area();
let expected = BoundingArea::new(-10.590682, 17.025842, 32.495452, 59.892292);
 
assert_eq!(expected, actual);
Source§

impl Polygon2D

Source

pub fn get_with_removed_neighbour_duplicates_with_tolerance( &self, tolerance: f64, ) -> Polygon2D

Creates new Polygon2D, but without vertices (which are neighbours) and eq_with_tolerance.

It can be useful for cleaning the duplicate vertices.

§Example
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(15.044527, 59.892292), // duplicate
    Point2D::new(15.044527, 59.892292), // duplicate
    Point2D::new(15.044527, 59.892292), // duplicate
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(12.375818, 37.208257), // duplicate within tolerance
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
    Point2D::new(-1.290632, 46.433122), // duplicate
]);

let actual = input.get_with_removed_neighbour_duplicates_with_tolerance(0.001);

let expected = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

assert_eq!(expected, actual);
Source

pub fn get_with_removed_neighbour_parallel_segments_with_tolerance( &self, angle_tolerance: f64, ) -> Polygon2D

Creates new Polygon2D, but without segments (which are neighbours) that are parallel.

It can be useful for cleaning unnecessary parallel segments.

tolerance is used here for angle measurement: if angle between segments’ vector is <= tolerance, then such segment should be removed.

§Example
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(16.683995, 49.46593), // parallel vertex
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(0.37224, 34.408898), // parallel vertex
    Point2D::new(-0.530578, 33.490333), // parallel vertex
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

let actual = input.get_with_removed_neighbour_parallel_segments_with_tolerance(0.01);

let expected = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

assert_eq!(expected, actual);
Source§

impl Polygon2D

Source

pub fn reverse(&mut self)

Reverse given Polygon2D.

§Example
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let mut input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);

input.reverse();

assert!(expected.eq(&input));
Source

pub fn get_reversed(&self) -> Polygon2D

Creates a new reversed version of given Polygon2D.

§Example
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);
 
let actual = input.get_reversed();
 
assert!(expected.eq(&actual));
 
Source

pub fn get_clockwise(&self) -> Polygon2D

Creates a new clockwise version of given Polygon2D.

Sometimes it’s easier to have all Polygons in one direction, that’s when such method might be useful.

§Examples

This example shows that the counter-clockwise Polygon2D is turned into clockwise.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let actual = input.get_clockwise();

assert!(expected.eq(&actual));

This example shows that the input Polygon is already clockwise, so new same direction Polygon is being returned.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let actual = input.get_clockwise();

assert!(expected.eq(&actual));
Source

pub fn get_anticlockwise(&self) -> Polygon2D

Creates a new anticlockwise version of given Polygon2D.

Sometimes it’s easier to have all Polygons in one direction, that’s when such method might be useful.

§Examples

This example shows that the clockwise Polygon2D is turned into anticlockwise.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(0.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(10.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);

let actual = input.get_anticlockwise();

assert!(expected.eq(&actual));

This example shows that the input Polygon is already anticlockwise, so new same direction Polygon is being returned.

use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);

let expected = Polygon2D::new(vec![Point2D::new(10.0, 0.0), Point2D::new(5.0, 10.0), Point2D::new(0.0, 0.0)]);

let actual = input.get_anticlockwise();

assert!(expected.eq(&actual));
Source§

impl Polygon2D

Source

pub fn triangulate_raw(&self) -> Mesh

Triangulates the Polygon2D using raw method introduced by iTriangle library.

§Example
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

let actual = input.triangulate_raw();
let expected = Mesh::new(
vec![-10.59068199054718, 46.39268698813629, 0.0, -8.141663988990784, 35.17492201449585, 0.0, -5.981672009391785, 50.8752869916172, 0.0, -5.091521998806, 42.510926986953734, 0.0, -1.4562550093364717, 32.54851099374008, 0.0, -1.2906320001316072, 46.43312200429153, 0.0, 3.0757680033016204, 55.3231370103569, 0.0, 3.1068030093479155, 37.19115700843048, 0.0, 7.725793013410568, 50.99659201028061, 0.0, 7.829036990242004, 32.495452011844634, 0.0, 12.375817010240555, 37.20825799824905, 0.0, 12.456687012748718, 46.06352298977089, 0.0, 13.184517005519867, 53.665302003643035, 0.0, 15.044527003602981, 59.892291988155364, 0.0, 16.86410198553085, 41.77741300584984, 0.0, 17.02584199054718, 49.05571200968933, 0.0],
vec![3, 0, 1, 4, 3, 1, 5, 3, 4, 6, 2, 5, 6, 5, 4, 7, 6, 4, 8, 6, 7, 9, 8, 7, 10, 8, 9, 11, 8, 10, 12, 8, 11, 13, 8, 12, 14, 12, 11, 15, 12, 14]
);

assert_eq!(expected, actual);
Source

pub fn triangulate_raw_with_holes(&self, holes: &Vec<Polygon2D>) -> Mesh

Triangulates the Polygon2D using raw method introduced by iTriangle library.

It also allows to define the holes.

§Example
use meshmeshmesh::mesh::Mesh;
use meshmeshmesh::point2d::Point2D;
use meshmeshmesh::polygon2d::Polygon2D;

let input = Polygon2D::new(vec![
    Point2D::new(-5.981672, 50.875287),
    Point2D::new(3.075768, 55.323137),
    Point2D::new(7.725793, 50.996592),
    Point2D::new(15.044527, 59.892292),
    Point2D::new(13.184517, 53.665302),
    Point2D::new(17.025842, 49.055712),
    Point2D::new(16.864102, 41.777413),
    Point2D::new(12.456687, 46.063523),
    Point2D::new(12.375817, 37.208258),
    Point2D::new(7.829037, 32.495452),
    Point2D::new(3.106803, 37.191157),
    Point2D::new(-1.456255, 32.548511),
    Point2D::new(-8.141664, 35.174922),
    Point2D::new(-10.590682, 46.392687),
    Point2D::new(-5.091522, 42.510927),
    Point2D::new(-1.290632, 46.433122),
]);

let hole1 = Polygon2D::new(vec![
    Point2D::new(4.911304, 46.578599),
    Point2D::new(14.34398, 51.393194),
    Point2D::new(16.276369, 45.890799),
    Point2D::new(13.852695, 45.628781),
    Point2D::new(11.298012, 48.085207),
]);

let hole2 = Polygon2D::new(vec![
   Point2D::new(7.017361, 49.601773),
   Point2D::new(2.205596, 52.068308),
   Point2D::new(-2.120949, 50.046558),
   Point2D::new(7.017361, 35.651698),
   Point2D::new(11.303471, 44.426093),
   Point2D::new(3.176036, 44.911313),
   Point2D::new(3.701691, 49.480468),
]);

let actual = input.triangulate_raw_with_holes(&vec![hole1, hole2]);
let expected = Mesh::new(
vec![-10.59068199054718, 46.39268698813629, 0.0, -8.141663988990784, 35.17492201449585, 0.0, -5.981672009391785, 50.8752869916172, 0.0, -5.091521998806, 42.510926986953734, 0.0, -2.1209489907455445, 50.04655798794937, 0.0, -1.4562550093364717, 32.54851099374008, 0.0, -1.2906320001316072, 46.43312200429153, 0.0, 2.2055960093307494, 52.06830799104881, 0.0, 3.0757680033016204, 55.3231370103569, 0.0, 3.1068030093479155, 37.19115700843048, 0.0, 3.1760360096263884, 44.911312992593764, 0.0, 3.7016910110282897, 49.48046800019455, 0.0, 4.911304006414413, 46.578599001190184, 0.0, 7.017360994653702, 35.65169798853111, 0.0, 7.017360994653702, 49.60177298905563, 0.0, 7.725793013410568, 50.99659201028061, 0.0, 7.829036990242004, 32.495452011844634, 0.0, 11.298011997776031, 48.08520701052856, 0.0, 11.303471008377075, 44.426093007347106, 0.0, 12.375817010240555, 37.20825799824905, 0.0, 12.456687012748718, 46.06352298977089, 0.0, 13.184517005519867, 53.665302003643035, 0.0, 13.85269499762535, 45.62878098609161, 0.0, 14.343979993896484, 51.39319398524475, 0.0, 15.044527003602981, 59.892291988155364, 0.0, 16.276369014816282, 45.89079901101303, 0.0, 16.86410198553085, 41.77741300584984, 0.0, 17.02584199054718, 49.05571200968933, 0.0],
vec![3, 0, 1, 5, 3, 1, 6, 3, 5, 6, 4, 2, 7, 2, 4, 8, 2, 7, 9, 6, 5, 9, 4, 6, 12, 11, 10, 13, 4, 9, 14, 11, 12, 14, 8, 7, 15, 8, 14, 16, 13, 9, 17, 12, 10, 18, 13, 16, 18, 17, 10, 19, 18, 16, 19, 17, 18, 20, 17, 19, 21, 15, 14, 21, 14, 12, 22, 17, 20, 23, 21, 12, 24, 15, 21, 26, 22, 20, 26, 25, 22, 27, 21, 23, 27, 23, 25, 27, 25, 26]
);

assert_eq!(expected, actual);

Trait Implementations§

Source§

impl Debug for Polygon2D

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl PartialEq for Polygon2D

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.