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)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct PolyShape {
|
pub struct PolyShape {
|
||||||
pub polygon: Polygon,
|
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 {
|
impl ShapeTrait for PolyShape {
|
||||||
fn center(&self) -> Point {
|
fn center(&self) -> Point {
|
||||||
self.polygon.centroid().unwrap()
|
self.polygon.centroid().unwrap()
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use geo::{point, polygon, Contains, EuclideanDistance, Intersects, Point, Polygo
|
||||||
use rstar::{RTreeObject, AABB};
|
use rstar::{RTreeObject, AABB};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
geometry::shape::ShapeTrait,
|
geometry::shape::{MeasureLength, ShapeTrait},
|
||||||
math::{self, Circle},
|
math::{self, Circle},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -14,7 +14,6 @@ pub trait PrimitiveShapeTrait: ShapeTrait {
|
||||||
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
fn intersects(&self, other: &PrimitiveShape) -> bool;
|
||||||
fn envelope(&self, margin: f64) -> AABB<[f64; 2]>;
|
fn envelope(&self, margin: f64) -> AABB<[f64; 2]>;
|
||||||
fn width(&self) -> f64;
|
fn width(&self) -> f64;
|
||||||
fn length(&self) -> f64;
|
|
||||||
|
|
||||||
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
|
fn envelope_3d(&self, margin: f64, layer: usize) -> AABB<[f64; 3]> {
|
||||||
let envelope = self.envelope(margin);
|
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)]
|
#[derive(Debug, Clone, Copy, PartialEq)]
|
||||||
pub enum PrimitiveShape {
|
pub enum PrimitiveShape {
|
||||||
// Intentionally in different order to reorder `self.intersects(...)` properly.
|
// Intentionally in different order to reorder `self.intersects(...)` properly.
|
||||||
|
|
@ -51,6 +50,12 @@ pub struct DotShape {
|
||||||
pub circle: Circle,
|
pub circle: Circle,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl MeasureLength for DotShape {
|
||||||
|
fn length(&self) -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl ShapeTrait for DotShape {
|
impl ShapeTrait for DotShape {
|
||||||
fn center(&self) -> Point {
|
fn center(&self) -> Point {
|
||||||
self.circle.pos
|
self.circle.pos
|
||||||
|
|
@ -122,10 +127,6 @@ impl PrimitiveShapeTrait for DotShape {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.circle.r * 2.0
|
self.circle.r * 2.0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn length(&self) -> f64 {
|
|
||||||
0.0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[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 {
|
impl ShapeTrait for SegShape {
|
||||||
fn center(&self) -> Point {
|
fn center(&self) -> Point {
|
||||||
(self.from + self.to) / 2.0
|
(self.from + self.to) / 2.0
|
||||||
|
|
@ -225,10 +232,6 @@ impl PrimitiveShapeTrait for SegShape {
|
||||||
fn width(&self) -> f64 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
self.width
|
||||||
}
|
}
|
||||||
|
|
||||||
fn length(&self) -> f64 {
|
|
||||||
self.to.euclidean_distance(&self.from)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
#[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 {
|
impl ShapeTrait for BendShape {
|
||||||
fn center(&self) -> Point {
|
fn center(&self) -> Point {
|
||||||
let sum = (self.from - self.inner_circle.pos) + (self.to - self.inner_circle.pos);
|
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 {
|
fn width(&self) -> f64 {
|
||||||
self.width
|
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 {
|
impl RTreeObject for PrimitiveShape {
|
||||||
|
|
|
||||||
|
|
@ -7,12 +7,17 @@ use crate::geometry::{
|
||||||
};
|
};
|
||||||
|
|
||||||
#[enum_dispatch]
|
#[enum_dispatch]
|
||||||
pub trait ShapeTrait {
|
pub trait MeasureLength {
|
||||||
|
fn length(&self) -> f64;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[enum_dispatch]
|
||||||
|
pub trait ShapeTrait: MeasureLength {
|
||||||
fn center(&self) -> Point;
|
fn center(&self) -> Point;
|
||||||
fn contains_point(&self, p: Point) -> bool;
|
fn contains_point(&self, p: Point) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[enum_dispatch(ShapeTrait)]
|
#[enum_dispatch(MeasureLength, ShapeTrait)]
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Shape {
|
pub enum Shape {
|
||||||
Dot(DotShape),
|
Dot(DotShape),
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,10 @@ use crate::{
|
||||||
wraparoundable::WraparoundableIndex,
|
wraparoundable::WraparoundableIndex,
|
||||||
Drawing, Infringement, LayoutException,
|
Drawing, Infringement, LayoutException,
|
||||||
},
|
},
|
||||||
geometry::{compound::CompoundManagerTrait, primitive::PrimitiveShapeTrait, GenericNode},
|
geometry::{
|
||||||
|
compound::CompoundManagerTrait, primitive::PrimitiveShapeTrait, shape::MeasureLength,
|
||||||
|
GenericNode,
|
||||||
|
},
|
||||||
graph::{GenericIndex, GetPetgraphIndex},
|
graph::{GenericIndex, GetPetgraphIndex},
|
||||||
layout::{
|
layout::{
|
||||||
via::{Via, ViaWeight},
|
via::{Via, ViaWeight},
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,10 @@ use crate::{
|
||||||
primitive::MakePrimitiveShape,
|
primitive::MakePrimitiveShape,
|
||||||
rules::RulesTrait,
|
rules::RulesTrait,
|
||||||
},
|
},
|
||||||
geometry::{primitive::PrimitiveShapeTrait, shape::ShapeTrait},
|
geometry::{
|
||||||
|
primitive::PrimitiveShapeTrait,
|
||||||
|
shape::{MeasureLength, ShapeTrait},
|
||||||
|
},
|
||||||
graph::GetPetgraphIndex,
|
graph::GetPetgraphIndex,
|
||||||
layout::Layout,
|
layout::Layout,
|
||||||
router::{
|
router::{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue