physdes/lib.rs
1//! # physdes-rs
2//!
3//! A library for Physical Design in Rust with geometric operations and algorithms.
4//!
5//! ## Overview
6//!
7//! ```svgbob
8//! Point (x, y)
9//! *
10//! /|\
11//! / | \
12//! / | \
13//! / | \
14//! *----*----*
15//! Interval [lb, ub]
16//!
17//! Vector2 (x, y)
18//! -->
19//! (dx, dy)
20//! ```
21//!
22//! ## Main Components
23//!
24//! The library provides several geometric structures:
25//!
26//! - `Point<T1, T2>`: A 2D point with x and y coordinates
27//! - `Vector2<T1, T2>`: A 2D vector with x and y components
28//! - `Interval<T>`: A range with lower and upper bounds
29//! - `Polygon<T>`: An arbitrary polygon
30//! - `RPolygon<T>`: A rectilinear polygon
31//! - `GeomError`: Error types for geometric operations
32//! - `vlsi_ops`: VLSI-specific geometric operations
33//! - `algorithms`: Additional geometric algorithms
34//!
35//! # Examples
36//!
37//! ```
38//! use physdes::{Point, Vector2};
39//! use physdes::interval::Interval;
40//! use physdes::polygon::Polygon as Poly;
41//!
42//! // Create a point
43//! let p = Point::new(3, 4);
44//! assert_eq!(p.xcoord, 3);
45//! assert_eq!(p.ycoord, 4);
46//!
47//! // Create a vector
48//! let v = Vector2::new(1, 2);
49//! assert_eq!(v.x_, 1);
50//! assert_eq!(v.y_, 2);
51//!
52//! // Create an interval
53//! let interval = Interval::new(1, 5);
54//! assert_eq!(interval.lb(), 1);
55//! assert_eq!(interval.ub(), 5);
56//!
57//! // Create a polygon from points
58//! let points = vec![Point::new(0, 0), Point::new(1, 0), Point::new(1, 1), Point::new(0, 1)];
59//! let polygon = Poly::new(&points);
60//! assert_eq!(polygon.origin, Point::new(0, 0));
61//! ```
62//!
63/// Geometric algorithms module
64pub mod algorithms;
65/// Doubly-linked list node for polygon decomposition
66pub mod dllink;
67/// DME algorithm for clock tree synthesis
68pub mod dme_algorithm;
69/// SVG visualizer for DME clock trees
70pub mod dme_visualizer;
71/// Error types for geometric operations
72pub mod error;
73/// Generic traits for geometric operations
74pub mod generic;
75/// Global router for Steiner tree routing
76pub mod global_router;
77/// Interval operations and types
78pub mod interval;
79/// Manhattan arc geometry for the DME algorithm
80pub mod manhattan_arc;
81/// Merge object for combining geometric objects
82pub mod merge_obj;
83/// Point types and operations
84pub mod point;
85/// Polygon types and operations
86pub mod polygon;
87/// Circular doubly-linked list for polygon decomposition
88pub mod rdllist;
89/// Rectilinear polygon types and operations
90pub mod rpolygon;
91/// Rectilinear polygon cut (decomposition) operations
92pub mod rpolygon_cut;
93/// Rectilinear polygon hull operations
94pub mod rpolygon_hull;
95/// Vector2 types and operations
96pub mod vector2;
97/// VLSI-specific geometric operations
98pub mod vlsi_ops;
99
100/// Logging module - available when `std` feature is enabled.
101#[cfg(feature = "std")]
102pub mod logging;
103
104pub use crate::point::Point;
105pub use crate::polygon::Polygon;
106pub use crate::rpolygon::RPolygon;
107pub use crate::vector2::Vector2;
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112 use quickcheck_macros::quickcheck;
113
114 #[test]
115 pub fn it_works() {
116 let pt_a = Point::<i32, i32>::new(12, 23);
117 let vec_b = Vector2::<i32, i32>::new(34, 45);
118 println!("{:?}", pt_a + vec_b);
119 println!("{:?}", pt_a - vec_b);
120
121 let mut pt_a = Point::<i32, i32>::new(42, 53);
122 pt_a += vec_b;
123 pt_a -= vec_b;
124 println!("{:?}", -pt_a);
125
126 let pt_nested = Point::<Point<i32, i32>, Point<i32, i32>>::new(pt_a, pt_a);
127 println!("{:?}", pt_nested);
128
129 let interval_x = interval::Interval::<i32>::new(12, 23);
130 // let interval_y = interval::Interval::<i32>::new(42, 53);
131 println!("{:?}", interval_x);
132 }
133
134 #[quickcheck]
135 fn check_point(ax: u16, bx: u16) -> bool {
136 let pt_a = Point::<i32, i32>::new(ax as i32, 23);
137 let vec_b = Vector2::<i32, i32>::new(bx as i32, 45);
138 pt_a == (pt_a - vec_b) + vec_b
139 }
140
141 // Additional quickcheck tests to verify build configuration
142 #[quickcheck]
143 fn check_point_arithmetic_properties(x: i16, y: i16, dx: i16, dy: i16) -> bool {
144 let pt = Point::<i32, i32>::new(x as i32, y as i32);
145 let vec = Vector2::<i32, i32>::new(dx as i32, dy as i32);
146
147 // Test associative property: (pt + vec) - vec == pt
148 let result = (pt + vec) - vec;
149 pt == result
150 }
151
152 #[quickcheck]
153 fn check_interval_properties(a: i32, b: i32) -> bool {
154 let lower = a.min(b);
155 let upper = a.max(b);
156 let interval = interval::Interval::<i32>::new(lower, upper);
157
158 // Test that the interval has correct bounds
159 interval.lb() <= interval.ub()
160 }
161
162 #[test]
163 fn test_const_functions() {
164 // Test that the const functions we added actually work in const contexts
165 const _P1: Point<i32, i32> = Point::new(1, 2);
166 const _I1: interval::Interval<i32> = interval::Interval::new(1, 5);
167 const _LB: i32 = _I1.lb();
168 const _UB: i32 = _I1.ub();
169 const _M1: merge_obj::MergeObj<i32, i32> = merge_obj::MergeObj::new(1, 2);
170 }
171}