ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
basic_usage.cpp
Go to the documentation of this file.
1
10
11#include <iostream>
12#include <vector>
13#include <chrono>
14#include <iomanip>
15#include <zlayout/zlayout.hpp>
16
17using namespace zlayout;
18using namespace zlayout::geometry;
19using namespace zlayout::spatial;
20
21void print_separator(const std::string& title) {
22 std::cout << "\n" << std::string(60, '=') << std::endl;
23 std::cout << " " << title << std::endl;
24 std::cout << std::string(60, '=') << std::endl;
25}
26
28 print_separator("Basic Geometry Features");
29
30 // Create points
31 Point p1(0.0, 0.0);
32 Point p2(3.0, 4.0);
33 Point p3(1.0, 1.0);
34
35 std::cout << "Point 1: " << p1 << std::endl;
36 std::cout << "Point 2: " << p2 << std::endl;
37 std::cout << "Distance from Point 1 to Point 2: " << std::fixed << std::setprecision(3)
38 << p1.distance_to(p2) << std::endl;
39
40 // Create rectangles
41 Rectangle rect1(0.0, 0.0, 10.0, 5.0);
42 Rectangle rect2(5.0, 2.0, 8.0, 6.0);
43
44 std::cout << "\nRectangle 1: " << rect1 << std::endl;
45 std::cout << "Rectangle 2: " << rect2 << std::endl;
46 std::cout << "Rectangles intersect: " << (rect1.intersects(rect2) ? "Yes" : "No") << std::endl;
47 std::cout << "Point " << p3 << " is inside Rectangle 1: " << (rect1.contains_point(p3) ? "Yes" : "No") << std::endl;
48
49 // Create triangle
50 Polygon triangle({Point(0.0, 0.0), Point(4.0, 0.0), Point(2.0, 3.0)});
51
52 std::cout << "\nTriangle: " << triangle << std::endl;
53 std::cout << "Triangle area: " << std::fixed << std::setprecision(2)
54 << triangle.area() << std::endl;
55 std::cout << "Triangle is convex: " << (triangle.is_convex() ? "Yes" : "No") << std::endl;
56}
57
59 print_separator("Interview Problem 1: Sharp Angle Detection");
60
61 // Create polygons with sharp angles
62 std::vector<Polygon> test_polygons = {
63 // Standard triangle
64 Polygon({Point(0.0, 0.0), Point(4.0, 0.0), Point(2.0, 3.0)}),
65
66 // Polygon with sharp angle
67 Polygon({Point(0.0, 0.0), Point(10.0, 0.0), Point(1.0, 1.0), Point(0.0, 10.0)}),
68
69 // L-shape
70 Polygon({Point(0.0, 0.0), Point(3.0, 0.0), Point(3.0, 1.0),
71 Point(1.0, 1.0), Point(1.0, 3.0), Point(0.0, 3.0)}),
72
73 // Polygon with very sharp angle
74 Polygon({Point(5.0, 5.0), Point(15.0, 5.1), Point(6.0, 8.0)})
75 };
76
77 std::vector<std::string> polygon_names = {
78 "Standard Triangle", "Sharp Angle Polygon", "L-Shape Polygon", "Acute Triangle"
79 };
80
81 double threshold_degrees = 45.0;
82 std::cout << "Sharp angle threshold: " << threshold_degrees << " degrees" << std::endl;
83
84 for (size_t i = 0; i < test_polygons.size(); ++i) {
85 std::cout << "\n--- " << polygon_names[i] << " ---" << std::endl;
86
87 auto sharp_angles = test_polygons[i].get_sharp_angles(threshold_degrees);
88 std::cout << "Found " << sharp_angles.size() << " sharp angles" << std::endl;
89
90 if (!sharp_angles.empty()) {
91 std::cout << "Sharp angle positions and angles:" << std::endl;
92 for (size_t vertex_idx : sharp_angles) {
93 double angle = test_polygons[i].vertex_angle(vertex_idx);
94 std::cout << " Vertex " << vertex_idx << ": "
95 << std::fixed << std::setprecision(1) << angle << "°" << std::endl;
96 }
97 }
98
99 // Show all angles
100 auto all_angles = test_polygons[i].all_vertex_angles();
101 std::cout << "All vertex angles: ";
102 for (size_t j = 0; j < all_angles.size(); ++j) {
103 if (j > 0) std::cout << ", ";
104 std::cout << std::fixed << std::setprecision(1) << all_angles[j] << "°";
105 }
106 std::cout << std::endl;
107 }
108}
109
111 print_separator("Interview Problem 2: Narrow Distance Detection");
112
113 // Create test polygon pairs
114 std::vector<std::pair<Polygon, Polygon>> test_pairs = {
115 // Close rectangles
116 {Polygon({Point(0, 0), Point(5, 0), Point(5, 3), Point(0, 3)}),
117 Polygon({Point(6, 0), Point(11, 0), Point(11, 3), Point(6, 3)})},
118
119 // Overlapping polygons
120 {Polygon({Point(0, 0), Point(8, 0), Point(8, 5), Point(0, 5)}),
121 Polygon({Point(6, 2), Point(14, 2), Point(14, 7), Point(6, 7)})},
122
123 // Close triangles
124 {Polygon({Point(0, 0), Point(3, 0), Point(1.5, 2)}),
125 Polygon({Point(3.2, 0), Point(6.2, 0), Point(4.7, 2)})},
126 };
127
128 std::vector<std::string> pair_names = {
129 "Adjacent Rectangles", "Overlapping Rectangles", "Adjacent Triangles"
130 };
131
132 double threshold_distance = 2.0;
133 std::cout << "Narrow distance threshold: " << threshold_distance << " units" << std::endl;
134
135 for (size_t i = 0; i < test_pairs.size(); ++i) {
136 std::cout << "\n--- " << pair_names[i] << " ---" << std::endl;
137
138 const auto& poly1 = test_pairs[i].first;
139 const auto& poly2 = test_pairs[i].second;
140
141 // Calculate minimum distance
142 double min_distance = poly1.distance_to(poly2);
143 std::cout << "Minimum distance: " << std::fixed << std::setprecision(3)
144 << min_distance << " units" << std::endl;
145
146 // Find narrow distance regions
147 auto narrow_regions = poly1.find_narrow_regions(poly2, threshold_distance);
148 std::cout << "Narrow distance regions: " << narrow_regions.size() << std::endl;
149
150 if (!narrow_regions.empty()) {
151 std::cout << "Narrow distance details:" << std::endl;
152 for (size_t j = 0; j < narrow_regions.size(); ++j) {
153 auto [point1, point2, distance] = narrow_regions[j];
154 std::cout << " Region " << (j+1) << ": " << point1 << " to " << point2
155 << ", distance " << std::fixed << std::setprecision(3) << distance << std::endl;
156 }
157 }
158
159 // Check for intersection
160 if (poly1.intersects(poly2)) {
161 std::cout << "WARNING: Polygons intersect!" << std::endl;
162 auto intersections = poly1.intersection_points(poly2);
163 std::cout << "Intersection points: " << intersections.size() << std::endl;
164 }
165 }
166}
167
169 print_separator("Interview Problem 3: Quadtree-Optimized Edge Intersection");
170
171 // Create multiple test components
172 std::vector<Rectangle> rectangles = {
173 Rectangle(10, 10, 5, 5), // Component 1
174 Rectangle(20, 20, 8, 6), // Component 2
175 Rectangle(50, 50, 12, 8), // Component 3
176 Rectangle(75, 25, 6, 10), // Component 4
177 Rectangle(15, 35, 5, 3), // Component 5 (may be close to others)
178 Rectangle(21, 35, 5, 3), // Component 6 (close to Component 5)
179 };
180
181 // Set world boundaries
182 Rectangle world_bounds(0, 0, 100, 100);
183
184 // Create quadtree (using lambda to provide bounding box function)
185 auto rect_quadtree = QuadTree<Rectangle>(
186 world_bounds,
187 [](const Rectangle& rect) -> Rectangle { return rect; }, // Rectangle is its own bounding box
188 3, // Capacity
189 4 // Max depth
190 );
191
192 std::cout << "Inserting " << rectangles.size() << " rectangle components into quadtree..." << std::endl;
193
194 // Insert all rectangles
195 auto start_time = std::chrono::high_resolution_clock::now();
196 for (size_t i = 0; i < rectangles.size(); ++i) {
197 bool success = rect_quadtree.insert(rectangles[i]);
198 std::cout << " Component " << (i+1) << ": " << (success ? "Success" : "Failed") << std::endl;
199 }
200 auto end_time = std::chrono::high_resolution_clock::now();
201 auto insert_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
202
203 std::cout << "Insertion time: " << insert_duration.count() << " microseconds" << std::endl;
204 std::cout << "Quadtree size: " << rect_quadtree.size() << " objects" << std::endl;
205
206 // Range query test
207 std::cout << "\n--- Range Query Test ---" << std::endl;
208 Rectangle query_region(0, 0, 30, 30);
209
210 start_time = std::chrono::high_resolution_clock::now();
211 auto objects_in_region = rect_quadtree.query_range(query_region);
212 end_time = std::chrono::high_resolution_clock::now();
213 auto query_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
214
215 std::cout << "Query region " << query_region << std::endl;
216 std::cout << "Found " << objects_in_region.size() << " objects" << std::endl;
217 std::cout << "Query time: " << query_duration.count() << " microseconds" << std::endl;
218
219 // Point query test
220 std::cout << "\n--- Point Query Test ---" << std::endl;
221 Point query_point(12, 12);
222
223 start_time = std::chrono::high_resolution_clock::now();
224 auto containing_objects = rect_quadtree.query_point(query_point);
225 end_time = std::chrono::high_resolution_clock::now();
226 auto point_query_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
227
228 std::cout << "Query point " << query_point << std::endl;
229 std::cout << "Found " << containing_objects.size() << " objects containing the point" << std::endl;
230 std::cout << "Point query time: " << point_query_duration.count() << " microseconds" << std::endl;
231
232 // Potential intersection detection
233 std::cout << "\n--- Potential Intersection Detection ---" << std::endl;
234 start_time = std::chrono::high_resolution_clock::now();
235 auto potential_intersections = rect_quadtree.find_potential_intersections();
236 end_time = std::chrono::high_resolution_clock::now();
237 auto intersection_duration = std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time);
238
239 std::cout << "Found " << potential_intersections.size() << " pairs of potentially intersecting objects" << std::endl;
240 std::cout << "Intersection detection time: " << intersection_duration.count() << " microseconds" << std::endl;
241
242 // Actual intersection verification
243 std::cout << "\nVerifying actual intersections:" << std::endl;
244 size_t actual_intersections = 0;
245 for (const auto& pair : potential_intersections) {
246 if (pair.first.intersects(pair.second)) {
247 actual_intersections++;
248 std::cout << " Actual intersection: " << pair.first << " with " << pair.second << std::endl;
249 }
250 }
251 std::cout << "Actual intersection pairs: " << actual_intersections << std::endl;
252
253 // Quadtree statistics
254 auto stats = rect_quadtree.get_statistics();
255 std::cout << "\n--- Quadtree Performance Statistics ---" << std::endl;
256 std::cout << "Total nodes: " << stats.total_nodes << std::endl;
257 std::cout << "Leaf nodes: " << stats.leaf_nodes << std::endl;
258 std::cout << "Max depth: " << stats.max_depth_reached << std::endl;
259 std::cout << "Average objects per leaf: " << std::fixed << std::setprecision(2)
260 << stats.average_objects_per_leaf << std::endl;
261 std::cout << "Tree efficiency: " << std::fixed << std::setprecision(3)
262 << stats.tree_efficiency << std::endl;
263}
264
266 print_separator("EDA Design Rule Check Example");
267
268 // Simulate EDA components
269 std::vector<Polygon> eda_components = {
270 // Microcontroller (rectangle)
271 Polygon({Point(30, 40), Point(45, 40), Point(45, 55), Point(30, 55)}),
272
273 // Resistor (small rectangle)
274 Polygon({Point(60, 50), Point(66, 50), Point(66, 52), Point(60, 52)}),
275
276 // Capacitor (small rectangle)
277 Polygon({Point(70, 65), Point(74, 65), Point(74, 68), Point(70, 68)}),
278
279 // Connector (with sharp angle)
280 Polygon({Point(110, 20), Point(125, 22), Point(112, 28), Point(108, 24)}),
281
282 // Trace (narrow polygon)
283 Polygon({Point(45, 47), Point(60, 50), Point(60, 50.2), Point(45, 47.2)}),
284
285 // Potentially overlapping components
286 Polygon({Point(40, 50), Point(55, 52), Point(53, 65), Point(38, 63)}),
287 Polygon({Point(50, 55), Point(65, 57), Point(63, 70), Point(48, 68)})
288 };
289
290 std::vector<std::string> component_names = {
291 "Microcontroller", "Resistor", "Capacitor", "Connector", "Trace", "Component A", "Component B"
292 };
293
294 // Different process design rules
295 struct ProcessRules {
296 std::string name;
297 double min_spacing;
298 double sharp_angle_limit;
299 };
300
301 std::vector<ProcessRules> processes = {
302 {"Prototype", 0.1, 20.0},
303 {"Standard", 0.15, 30.0},
304 {"High Precision", 0.05, 45.0}
305 };
306
307 std::cout << "Analyzing " << eda_components.size() << " EDA components..." << std::endl;
308
309 for (const auto& process : processes) {
310 std::cout << "\n--- " << process.name << " Process Check ---" << std::endl;
311 std::cout << "Min spacing: " << process.min_spacing << ", Sharp angle limit: "
312 << process.sharp_angle_limit << "°" << std::endl;
313
314 int violations = 0;
315
316 // Sharp angle check
317 std::cout << "\nSharp angle check:" << std::endl;
318 for (size_t i = 0; i < eda_components.size(); ++i) {
319 auto sharp_angles = eda_components[i].get_sharp_angles(process.sharp_angle_limit);
320 if (!sharp_angles.empty()) {
321 violations += static_cast<int>(sharp_angles.size());
322 std::cout << " " << component_names[i] << ": " << sharp_angles.size()
323 << " sharp angle violations" << std::endl;
324 }
325 }
326
327 // Spacing check
328 std::cout << "\nSpacing check:" << std::endl;
329 for (size_t i = 0; i < eda_components.size(); ++i) {
330 for (size_t j = i + 1; j < eda_components.size(); ++j) {
331 double distance = eda_components[i].distance_to(eda_components[j]);
332 if (distance < process.min_spacing) {
333 violations++;
334 std::cout << " " << component_names[i] << " and " << component_names[j]
335 << ": distance " << std::fixed << std::setprecision(3)
336 << distance << " < " << process.min_spacing << std::endl;
337 }
338 }
339 }
340
341 // Intersection check
342 std::cout << "\nIntersection check:" << std::endl;
343 for (size_t i = 0; i < eda_components.size(); ++i) {
344 for (size_t j = i + 1; j < eda_components.size(); ++j) {
345 if (eda_components[i].intersects(eda_components[j])) {
346 violations++;
347 std::cout << " " << component_names[i] << " and " << component_names[j]
348 << ": intersection violation" << std::endl;
349 }
350 }
351 }
352
353 // Summary
354 if (violations == 0) {
355 std::cout << "PASS: " << process.name << " process check" << std::endl;
356 } else {
357 std::cout << "FAIL: " << violations << " violations, does not meet " << process.name
358 << " process requirements" << std::endl;
359 }
360 }
361}
362
363int main() {
364 std::cout << "ZLayout C++ - High Performance EDA Layout Processing Library" << std::endl;
365 std::cout << "Version: " << zlayout::get_version() << std::endl;
366
367 // Initialize library
368 if (!zlayout::initialize()) {
369 std::cerr << "Library initialization failed!" << std::endl;
370 return 1;
371 }
372
373 try {
374 // Demonstrate basic geometry features
376
377 // Demonstrate interview problem solutions
381
382 // Demonstrate EDA application
384
385 print_separator("Demo Complete");
386 std::cout << "All feature demonstrations completed successfully!" << std::endl;
387 std::cout << "\nCore algorithm performance:" << std::endl;
388 std::cout << " - Sharp angle detection: O(n) per polygon" << std::endl;
389 std::cout << " - Narrow distance detection: O(n²) optimized with bounding box pre-filtering" << std::endl;
390 std::cout << " - Quadtree intersection detection: O(log n) average query complexity" << std::endl;
391
392 } catch (const std::exception& e) {
393 std::cerr << "Error: " << e.what() << std::endl;
394 return 1;
395 }
396
397 // Clean up resources
399
400 return 0;
401}
void demonstrate_narrow_distance_detection()
void demonstrate_basic_geometry()
void demonstrate_quadtree_intersection_detection()
void demonstrate_eda_design_rules()
void print_separator(const std::string &title)
void demonstrate_sharp_angle_detection()
int main()
2D point with high-precision coordinates and utility methods
Definition point.hpp:23
double distance_to(const Point &other) const
Calculate Euclidean distance to another point.
Definition point.cpp:56
Polygon class supporting both convex and concave polygons.
Definition polygon.hpp:25
double area() const
Calculate polygon area using shoelace formula.
Definition polygon.cpp:47
Axis-aligned rectangle for bounding boxes and simple EDA components.
Definition rectangle.hpp:26
bool intersects(const Rectangle &other) const
Check if this rectangle intersects with another rectangle.
bool contains_point(const Point &point) const
Check if point is inside rectangle (inclusive of boundary)
Definition rectangle.cpp:89
Quadtree spatial index for efficient range and intersection queries.
Definition quadtree.hpp:120
double distance(const Point &p1, const Point &p2)
Calculate distance between two points.
Definition point.cpp:161
Main namespace for ZLayout library.
Definition component.hpp:20
bool initialize(bool enable_openmp=true)
Initialize ZLayout library.
Definition zlayout.cpp:30
void cleanup()
Cleanup ZLayout library resources.
Definition zlayout.cpp:72
const char * get_version()
Get library version string.
Definition zlayout.cpp:26
ZLayout - Advanced Electronic Design Automation Layout Library.