use derive_more::{Constructor, From};
use serde::{Deserialize, Serialize};
use crate::layout::compounds::{ComponentId, NetId, PinId};
use crate::vector::Vector2;
use crate::{Rect3, Vector3, layout::LayerId};
use super::{Joint, JointId};
#[derive(
Clone,
Constructor,
Copy,
Debug,
Default,
Deserialize,
Eq,
From,
Ord,
PartialEq,
PartialOrd,
Serialize,
)]
pub struct SegId(usize);
impl SegId {
#[inline]
pub fn index(self) -> usize {
self.0
}
}
#[derive(Clone, Copy, Debug)]
pub struct SegSpec {
pub endjoints: [JointId; 2],
pub half_width: u64,
pub component: Option<ComponentId>,
pub pin: Option<PinId>,
}
#[derive(Clone, Copy, Debug)]
pub struct Seg {
pub spec: SegSpec,
pub endpoints: [Vector2<i64>; 2],
pub layer: LayerId,
pub net: Option<NetId>,
}
impl Seg {
pub fn new(spec: SegSpec, endjoints: [&Joint; 2]) -> Self {
Self {
spec,
endpoints: [endjoints[0].spec.position, endjoints[1].spec.position],
layer: endjoints[0].spec.layer,
net: endjoints[0].spec.net,
}
}
pub fn center(&self) -> Vector2<i64> {
(self.endpoints[0] + self.endpoints[1]) / 2
}
pub fn contains_point2(&self, point: Vector2<i64>) -> bool {
let vertices = crate::math::inflated_seg(
self.endpoints[0].x,
self.endpoints[0].y,
self.endpoints[1].x,
self.endpoints[1].y,
self.spec.half_width,
);
point.inside_polygon(&vertices)
}
pub fn bounding_rectangle(&self) -> [Vector2<i64>; 4] {
crate::math::inflated_seg(
self.endpoints[0].x,
self.endpoints[0].y,
self.endpoints[1].x,
self.endpoints[1].y,
self.spec.half_width,
)
}
pub fn bbox(&self) -> Rect3<i64> {
let endpoints = self.endpoints;
let layer = self.layer.index() as i64;
let half_width = self.spec.half_width as i64;
Rect3::new(
Vector3::new(
std::cmp::min(endpoints[0].x, endpoints[1].x) - half_width,
std::cmp::min(endpoints[0].y, endpoints[1].y) - half_width,
layer,
),
Vector3::new(
std::cmp::max(endpoints[0].x, endpoints[1].x) + half_width,
std::cmp::max(endpoints[0].y, endpoints[1].y) + half_width,
layer,
),
)
}
}