ZLayout EDA Library v1.0.0
Advanced Electronic Design Automation Layout Library with Bilingual Documentation
Loading...
Searching...
No Matches
point.cpp
Go to the documentation of this file.
1
5
7#include <cmath>
8#include <sstream>
9#include <iomanip>
10
11namespace zlayout {
12namespace geometry {
13
14// Point class implementation
15
16bool Point::operator==(const Point& other) const {
17 return std::abs(x - other.x) < TOLERANCE &&
18 std::abs(y - other.y) < TOLERANCE;
19}
20
21bool Point::operator!=(const Point& other) const {
22 return !(*this == other);
23}
24
25Point Point::operator+(const Point& other) const {
26 return Point(x + other.x, y + other.y);
27}
28
29Point Point::operator-(const Point& other) const {
30 return Point(x - other.x, y - other.y);
31}
32
33Point Point::operator*(double scalar) const {
34 return Point(x * scalar, y * scalar);
35}
36
37Point Point::operator/(double scalar) const {
38 if (std::abs(scalar) < TOLERANCE) {
39 throw std::invalid_argument("Division by zero in Point::operator/");
40 }
41 return Point(x / scalar, y / scalar);
42}
43
45 x += other.x;
46 y += other.y;
47 return *this;
48}
49
51 x -= other.x;
52 y -= other.y;
53 return *this;
54}
55
56double Point::distance_to(const Point& other) const {
57 double dx = x - other.x;
58 double dy = y - other.y;
59 return std::sqrt(dx * dx + dy * dy);
60}
61
62double Point::distance_squared_to(const Point& other) const {
63 double dx = x - other.x;
64 double dy = y - other.y;
65 return dx * dx + dy * dy;
66}
67
68double Point::distance_to_line(const Point& line_start, const Point& line_end) const {
69 // Vector from line_start to line_end
70 Point line_vec = line_end - line_start;
71 double line_length_sq = line_vec.magnitude_squared();
72
73 // Handle degenerate line (point)
74 if (line_length_sq < TOLERANCE) {
75 return distance_to(line_start);
76 }
77
78 // Vector from line_start to this point
79 Point point_vec = *this - line_start;
80
81 // Project point onto line (parameter t)
82 double t = point_vec.dot(line_vec) / line_length_sq;
83
84 // Clamp t to [0, 1] to stay on line segment
85 t = std::max(0.0, std::min(1.0, t));
86
87 // Find closest point on line segment
88 Point closest = line_start + line_vec * t;
89
90 return distance_to(closest);
91}
92
93double Point::dot(const Point& other) const {
94 return x * other.x + y * other.y;
95}
96
97double Point::cross(const Point& other) const {
98 return x * other.y - y * other.x;
99}
100
101double Point::magnitude() const {
102 return std::sqrt(x * x + y * y);
103}
104
106 return x * x + y * y;
107}
108
110 double mag = magnitude();
111 if (mag < TOLERANCE) {
112 return Point(0.0, 0.0); // Return zero vector if magnitude is too small
113 }
114 return Point(x / mag, y / mag);
115}
116
117Point Point::rotate(double angle) const {
118 double cos_a = std::cos(angle);
119 double sin_a = std::sin(angle);
120 return Point(x * cos_a - y * sin_a, x * sin_a + y * cos_a);
121}
122
123Point Point::rotate_around(const Point& center, double angle) const {
124 Point translated = *this - center;
125 Point rotated = translated.rotate(angle);
126 return rotated + center;
127}
128
129double Point::angle_to(const Point& other) const {
130 Point vec = other - *this;
131 return std::atan2(vec.y, vec.x);
132}
133
134bool Point::is_zero() const {
135 return magnitude() < TOLERANCE;
136}
137
138std::string Point::to_string() const {
139 std::ostringstream oss;
140 oss << std::fixed << std::setprecision(6) << "Point(" << x << ", " << y << ")";
141 return oss.str();
142}
143
144std::ostream& operator<<(std::ostream& os, const Point& point) {
145 os << point.to_string();
146 return os;
147}
148
149// PointHash implementation
150
151std::size_t PointHash::operator()(const Point& point) const {
152 // Use a simple hash combining function
153 std::hash<double> hasher;
154 std::size_t h1 = hasher(std::round(point.x / Point::TOLERANCE) * Point::TOLERANCE);
155 std::size_t h2 = hasher(std::round(point.y / Point::TOLERANCE) * Point::TOLERANCE);
156 return h1 ^ (h2 << 1);
157}
158
159// Utility functions
160
161double distance(const Point& p1, const Point& p2) {
162 return p1.distance_to(p2);
163}
164
165Point midpoint(const Point& p1, const Point& p2) {
166 return Point((p1.x + p2.x) * 0.5, (p1.y + p2.y) * 0.5);
167}
168
169double angle_between_points(const Point& p1, const Point& p2, const Point& p3) {
170 // Calculate vectors from p2 to p1 and p2 to p3
171 Point v1 = p1 - p2;
172 Point v2 = p3 - p2;
173
174 // Calculate angle using dot product
175 double dot_product = v1.dot(v2);
176 double mag1 = v1.magnitude();
177 double mag2 = v2.magnitude();
178
179 if (mag1 < Point::TOLERANCE || mag2 < Point::TOLERANCE) {
180 return 0.0;
181 }
182
183 double cos_angle = dot_product / (mag1 * mag2);
184 // Clamp to [-1, 1] to handle numerical errors
185 cos_angle = std::max(-1.0, std::min(1.0, cos_angle));
186
187 return std::acos(cos_angle);
188}
189
190bool are_collinear(const Point& p1, const Point& p2, const Point& p3) {
191 // Calculate cross product to determine if points are collinear
192 Point v1 = p2 - p1;
193 Point v2 = p3 - p1;
194 double cross_product = v1.cross(v2);
195 return std::abs(cross_product) < Point::TOLERANCE;
196}
197
198int orientation(const Point& p1, const Point& p2, const Point& p3) {
199 // Calculate cross product to determine orientation
200 Point v1 = p2 - p1;
201 Point v2 = p3 - p2;
202 double cross_product = v1.cross(v2);
203
204 if (std::abs(cross_product) < Point::TOLERANCE) {
205 return 0; // Collinear
206 }
207 return (cross_product > 0) ? 1 : 2; // 1 for clockwise, 2 for counterclockwise
208}
209
210} // namespace geometry
211} // namespace zlayout
2D point with high-precision coordinates and utility methods
Definition point.hpp:23
bool operator==(const Point &other) const
Equality operator with tolerance.
Definition point.cpp:16
double cross(const Point &other) const
Calculate cross product magnitude (2D cross product)
Definition point.cpp:97
Point normalize() const
Normalize vector to unit length.
Definition point.cpp:109
double x
X coordinate.
Definition point.hpp:25
std::string to_string() const
Get string representation.
Definition point.cpp:138
double magnitude() const
Calculate vector magnitude (length)
Definition point.cpp:101
Point & operator+=(const Point &other)
Addition assignment.
Definition point.cpp:44
Point operator/(double scalar) const
Scalar division.
Definition point.cpp:37
double distance_squared_to(const Point &other) const
Calculate squared distance (faster, avoids sqrt)
Definition point.cpp:62
Point operator-(const Point &other) const
Subtraction operator.
Definition point.cpp:29
double distance_to_line(const Point &line_start, const Point &line_end) const
Calculate distance from this point to a line segment.
Definition point.cpp:68
Point rotate_around(const Point &center, double angle) const
Rotate point around another point by angle (radians)
Definition point.cpp:123
Point & operator-=(const Point &other)
Subtraction assignment.
Definition point.cpp:50
Point rotate(double angle) const
Rotate point around origin by angle (radians)
Definition point.cpp:117
static constexpr double TOLERANCE
Default precision tolerance for floating point comparisons.
Definition point.hpp:29
bool operator!=(const Point &other) const
Inequality operator.
Definition point.cpp:21
double magnitude_squared() const
Calculate squared magnitude (faster, avoids sqrt)
Definition point.cpp:105
double dot(const Point &other) const
Calculate dot product with another point (as vector)
Definition point.cpp:93
double angle_to(const Point &other) const
Calculate angle from this point to another (radians)
Definition point.cpp:129
double y
Y coordinate.
Definition point.hpp:26
Point operator+(const Point &other) const
Addition operator.
Definition point.cpp:25
double distance_to(const Point &other) const
Calculate Euclidean distance to another point.
Definition point.cpp:56
Point()
Default constructor - creates point at origin.
Definition point.hpp:34
Point operator*(double scalar) const
Scalar multiplication.
Definition point.cpp:33
bool is_zero() const
Check if point is approximately zero.
Definition point.cpp:134
std::ostream & operator<<(std::ostream &os, const Point &point)
Definition point.cpp:144
Point midpoint(const Point &p1, const Point &p2)
Calculate midpoint between two points.
Definition point.cpp:165
int orientation(const Point &p1, const Point &p2, const Point &p3)
Calculate orientation of three points.
Definition point.cpp:198
double distance(const Point &p1, const Point &p2)
Calculate distance between two points.
Definition point.cpp:161
bool are_collinear(const Point &p1, const Point &p2, const Point &p3)
Check if three points are collinear.
Definition point.cpp:190
double angle_between_points(const Point &p1, const Point &p2, const Point &p3)
Calculate angle between three points (p1-p2-p3)
Definition point.cpp:169
Main namespace for ZLayout library.
Definition component.hpp:20
2D Point class for geometric calculations
std::size_t operator()(const Point &point) const
Definition point.cpp:151