25void validateParams(
double x0,
double y0,
double x1,
double y1,
double t) {
26 constexpr double eps = 1.0e-12;
27 if (!(x1 > x0 + eps && y1 > y0 + eps && t > eps))
28 throw std::runtime_error(
29 "OpenRectChannel2D: require x0 < x1, y0 < y1, t > 0.");
30 if (!(x1 - x0 > 2. * t + eps && y1 - y0 > 2. * t + eps))
31 throw std::runtime_error(
32 "OpenRectChannel2D: require x1-x0 > 2t and y1-y0 > 2t so the U-channel exists.");
38 const double L2 = ab * ab;
41 double s = (ap * ab) / L2;
42 s = std::max(0., std::min(1., s));
44 return (p - proj).
length();
54 double z, std::string description)
55 :
GeomObject(
"open_rect_channel_2d", std::move(description)),
62 validateParams(x0, y0, x1, y1, t);
67 :
GeomObject(other.d_name, other.d_description),
74 d_vertices(other.d_vertices),
119 const size_t n = v.size();
120 for (
size_t i = 0, j = n - 1; i < n; j = i++) {
121 const double xi = v[i].d_x, yi = v[i].d_y;
122 const double xj = v[j].d_x, yj = v[j].d_y;
123 if (((yi > p.
d_y) != (yj > p.
d_y)) &&
124 (p.
d_x < (xj - xi) * (p.
d_y - yi) / (yj - yi + 1.0e-30) + xi))
135 const size_t n = v.size();
136 for (
size_t i = 0; i < n; ++i) {
137 const size_t j = (i + 1) % n;
138 a += v[i].d_x * v[j].d_y - v[j].d_x * v[i].d_y;
140 return 0.5 * std::abs(a);
147 double cx = 0., cy = 0.;
149 const size_t n = v.size();
150 for (
size_t i = 0; i < n; ++i) {
151 const size_t j = (i + 1) % n;
152 const double cross = v[i].
d_x * v[j].d_y - v[j].d_x * v[i].d_y;
154 cx += (v[i].d_x + v[j].d_x) * cross;
155 cy += (v[i].d_y + v[j].d_y) * cross;
157 if (std::abs(a) < 1.0e-30)
158 return {(v[0].d_x + v[1].d_x) * 0.5, (v[0].d_y + v[1].d_y) * 0.5, v[0].d_z};
160 return {cx / (6. * a), cy / (6. * a), v[0].d_z};
168 const util::Point pivot = rotationPoint !=
nullptr ? *rotationPoint :
d_x;
172 v = pivot +
util::rotate(v - pivot, angle, axis) * scale + translation;
198 util::Point lo(std::numeric_limits<double>::max(), std::numeric_limits<double>::max(),
199 std::numeric_limits<double>::max());
200 util::Point hi(-std::numeric_limits<double>::max(), -std::numeric_limits<double>::max(),
201 -std::numeric_limits<double>::max());
203 lo.
d_x = std::min(lo.
d_x, v.d_x);
204 lo.
d_y = std::min(lo.
d_y, v.d_y);
205 lo.
d_z = std::min(lo.
d_z, v.d_z);
206 hi.
d_x = std::max(hi.
d_x, v.d_x);
207 hi.
d_y = std::max(hi.
d_y, v.d_y);
208 hi.
d_z = std::max(hi.
d_z, v.d_z);
210 return {lo - tol, hi + tol};
221 r = std::max(r, (v - c).length());
226 if (std::abs(x.
d_z -
d_z) > 1.0e-9)
236 auto bbox =
box(tol);
241 const bool &within)
const {
242 if (!
isNear(x, within ? 0. : tol))
245 for (
size_t i = 0; i < n; ++i) {
266 bool intersect =
false;
274 const double &tol)
const {
287 std::ostringstream oss;
288 oss << tabS <<
"------- OpenRectChannel2D (U-channel, open +y) --------" << std::endl;
289 oss << tabS <<
"Outer box: [" <<
d_x0 <<
"," <<
d_y0 <<
"] — [" <<
d_x1 <<
"," <<
d_y1 <<
"], z="
290 <<
d_z <<
", t=" <<
d_t << std::endl;
Defines abstract geometrical domain.
std::vector< std::string > d_tags
Tags/attributes about the object.
2D U-shaped cavity: thick rectangular frame with the top (+y) side open.
std::pair< util::Point, util::Point > box() const override
Computes the bounding box of object.
bool pointInPolygon2D(const util::Point &p) const
bool isInside(const util::Point &x) const override
Checks if point is inside this object.
double inscribedRadius() const override
Computes the radius of biggest circle/sphere completely within the object.
util::Point center() const override
Computes the center of object.
util::Point polygonCentroid2D() const
OpenRectChannel2D & operator=(const OpenRectChannel2D &other)
void transform(const util::Point &translation, const double &scale, const double &angle, const util::Point &axis, const util::Point *rotationPoint) override
Similarity about pivot (default: old center d_x), then rigid displacement = translation: ....
std::vector< util::Point > d_vertices
CCW boundary of the U-shaped solid (10 vertices, uniform thickness t).
std::string printStr(int nt=0, int lvl=0) const override
Returns the string containing printable information about the object.
bool doesIntersect(const util::Point &x) const override
Checks if point lies exactly on the boundary.
bool isOutside(const util::Point &x) const override
Checks if point is outside of this object.
bool isNearBoundary(const util::Point &x, const double &tol, const bool &within) const override
Checks if point is within given distance of this object.
double boundingRadius() const override
Computes the radius of smallest circle/sphere such that object can be fit into it.
double polygonArea2D() const
util::Point d_x
Area centroid of the polygon (same convention as d_x on other GeomObjects).
bool isNear(const util::Point &x, const double &tol) const override
Checks if point is within given distance of this object.
double volume() const override
Computes the volume (area in 2d, length in 1d) of object.
double distPointToSegment2D(const util::Point &p, const util::Point &a, const util::Point &b)
bool isPointInsideBox(util::Point x, size_t dim, const std::pair< util::Point, util::Point > &box)
Returns true if point is inside box.
bool areBoxesNear(const std::pair< util::Point, util::Point > &b1, const std::pair< util::Point, util::Point > &b2, const double &tol, size_t dim)
Checks if given two boxes are within given distance from each other.
std::vector< util::Point > getCornerPoints(size_t dim, const std::pair< util::Point, util::Point > &box)
Returns all corner points in the box.
std::string getTabS(int nt)
Returns tab spaces of a given size.
std::string printStr(const T &msg, int nt=print_default_tab)
Returns formatted string for output.
bool isLess(const double &a, const double &b)
Returns true if a < b.
util::Point rotate(const util::Point &p, const double &theta, const util::Point &axis)
Returns the vector after rotating by desired angle.
A structure to represent 3d vectors.
double d_y
the y coordinate
double d_z
the z coordinate
double length() const
Computes the Euclidean length of the vector.
double d_x
the x coordinate