mirror of https://codeberg.org/topola/topola.git
geometry: create `MeasureLength` trait to measure lengths
This commit is contained in:
parent
27d1c9e712
commit
3c03b2dfa1
|
|
@ -1,12 +1,24 @@
|
|||
use geo::{Centroid, Contains, Point, Polygon};
|
||||
use geo::{Centroid, Contains, EuclideanLength, Point, Polygon};
|
||||
|
||||
use crate::geometry::shape::ShapeTrait;
|
||||
use crate::geometry::shape::{MeasureLength, ShapeTrait};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub struct PolyShape {
|
||||
pub polygon: Polygon,
|
||||
}
|
||||
|
||||
impl MeasureLength for PolyShape {
|
||||
fn length(&self) -> f64 {
|
||||
let mut length = 0.0;
|
||||
|
||||
for line in self.polygon.exterior().lines() {
|
||||
length += line.euclidean_length();
|
||||
}
|
||||
|
||||
length
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeTrait for PolyShape {
|
||||
fn center(&self) -> Point {
|
||||
self.polygon.centroid().unwrap()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ use geo::{point, polygon, Contains, EuclideanDistance, Intersects, Point, Polygo
|
|||
use rstar::{RTreeObject, AABB};
|
||||
|
||||
use crate::{
|
||||
geometry::shape::ShapeTrait,
|
||||
geometry::shape::{MeasureLength, ShapeTrait},
|
||||
math::{self, Circle},
|
||||
};
|
||||
|
||||
|
|
@ -14,7 +14,6 @@ pub trait PrimitiveShapeTrait: ShapeTrait {
|
|||
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
||||
fn envelope(&self, margin: f64) -> AABB<[f64; 2]>;
|
||||
fn width(&self) -> f64;
|
||||
fn length(&self) -> f64;
|
||||
|
||||
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
|
||||
let envelope = self.envelope(margin);
|
||||
|
|
@ -37,7 +36,7 @@ pub trait PrimitiveShapeTrait: ShapeTrait {
|
|||
}
|
||||
}
|
||||
|
||||
#[enum_dispatch(ShapeTrait, PrimitiveShapeTrait)]
|
||||
#[enum_dispatch(MeasureLength, ShapeTrait, PrimitiveShapeTrait)]
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
pub enum PrimitiveShape {
|
||||
// Intentionally in different order to reorder `self.intersects(...)` properly.
|
||||
|
|
@ -51,6 +50,12 @@ pub struct DotShape {
|
|||
pub circle: Circle,
|
||||
}
|
||||
|
||||
impl MeasureLength for DotShape {
|
||||
fn length(&self) -> f64 {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeTrait for DotShape {
|
||||
fn center(&self) -> Point {
|
||||
self.circle.pos
|
||||
|
|
@ -122,10 +127,6 @@ impl PrimitiveShapeTrait for DotShape {
|
|||
fn width(&self) -> f64 {
|
||||
self.circle.r * 2.0
|
||||
}
|
||||
|
||||
fn length(&self) -> f64 {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
|
@ -152,6 +153,12 @@ impl SegShape {
|
|||
}
|
||||
}
|
||||
|
||||
impl MeasureLength for SegShape {
|
||||
fn length(&self) -> f64 {
|
||||
self.to.euclidean_distance(&self.from)
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeTrait for SegShape {
|
||||
fn center(&self) -> Point {
|
||||
(self.from + self.to) / 2.0
|
||||
|
|
@ -225,10 +232,6 @@ impl PrimitiveShapeTrait for SegShape {
|
|||
fn width(&self) -> f64 {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn length(&self) -> f64 {
|
||||
self.to.euclidean_distance(&self.from)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||
|
|
@ -267,6 +270,22 @@ impl BendShape {
|
|||
}
|
||||
}
|
||||
|
||||
impl MeasureLength for BendShape {
|
||||
fn length(&self) -> f64 {
|
||||
// TODO: Not valid for inflated bends, as currently `from` and `to` of these don't lie on
|
||||
// teir circles.
|
||||
|
||||
// We obtain the angle from the law of cosines and multiply with radius to get the length.
|
||||
let d = self.to.euclidean_distance(&self.from);
|
||||
|
||||
if d > 0.0 {
|
||||
(1.0 - d * d / (2.0 * d * d)).acos()
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ShapeTrait for BendShape {
|
||||
fn center(&self) -> Point {
|
||||
let sum = (self.from - self.inner_circle.pos) + (self.to - self.inner_circle.pos);
|
||||
|
|
@ -351,20 +370,6 @@ impl PrimitiveShapeTrait for BendShape {
|
|||
fn width(&self) -> f64 {
|
||||
self.width
|
||||
}
|
||||
|
||||
fn length(&self) -> f64 {
|
||||
// TODO: Not valid for inflated bends, as currently `from` and `to` of these don't lie on
|
||||
// teir circles.
|
||||
|
||||
// We obtain the angle from the law of cosines and multiply with radius to get the length.
|
||||
let d = self.to.euclidean_distance(&self.from);
|
||||
|
||||
if d > 0.0 {
|
||||
(1.0 - d * d / (2.0 * d * d)).acos()
|
||||
} else {
|
||||
0.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl RTreeObject for PrimitiveShape {
|
||||
|
|
|
|||
|
|
@ -7,12 +7,17 @@ use crate::geometry::{
|
|||
};
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait ShapeTrait {
|
||||
pub trait MeasureLength {
|
||||
fn length(&self) -> f64;
|
||||
}
|
||||
|
||||
#[enum_dispatch]
|
||||
pub trait ShapeTrait: MeasureLength {
|
||||
fn center(&self) -> Point;
|
||||
fn contains_point(&self, p: Point) -> bool;
|
||||
}
|
||||
|
||||
#[enum_dispatch(ShapeTrait)]
|
||||
#[enum_dispatch(MeasureLength, ShapeTrait)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Shape {
|
||||
Dot(DotShape),
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ use crate::{
|
|||
wraparoundable::WraparoundableIndex,
|
||||
Drawing, Infringement, LayoutException,
|
||||
},
|
||||
geometry::{compound::CompoundManagerTrait, primitive::PrimitiveShapeTrait, GenericNode},
|
||||
geometry::{
|
||||
compound::CompoundManagerTrait, primitive::PrimitiveShapeTrait, shape::MeasureLength,
|
||||
GenericNode,
|
||||
},
|
||||
graph::{GenericIndex, GetPetgraphIndex},
|
||||
layout::{
|
||||
via::{Via, ViaWeight},
|
||||
|
|
|
|||
|
|
@ -11,7 +11,10 @@ use crate::{
|
|||
primitive::MakePrimitiveShape,
|
||||
rules::RulesTrait,
|
||||
},
|
||||
geometry::{primitive::PrimitiveShapeTrait, shape::ShapeTrait},
|
||||
geometry::{
|
||||
primitive::PrimitiveShapeTrait,
|
||||
shape::{MeasureLength, ShapeTrait},
|
||||
},
|
||||
graph::GetPetgraphIndex,
|
||||
layout::Layout,
|
||||
router::{
|
||||
|
|
|
|||
Loading…
Reference in New Issue