From 5daa507686936a4225d4f57c59d896991252b79e Mon Sep 17 00:00:00 2001 From: gjj Date: Sat, 23 Nov 2024 20:42:53 +0800 Subject: [PATCH] single arc line & readme doc --- .clang-tidy | 3 ++ README.md | 95 +++++++++++++++++++++++++++++++++- include/line.hpp | 128 ++++++++++++++++++++++------------------------ include/solid.hpp | 11 ++++ main.cpp | 16 ++---- 5 files changed, 174 insertions(+), 79 deletions(-) diff --git a/.clang-tidy b/.clang-tidy index 98d6506..edc9752 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -23,6 +23,9 @@ Checks: " -cppcoreguidelines-init-variables, -cppcoreguidelines-pro-type-member-init, " +CheckOptions: + - key: misc-non-private-member-variables-in-classes.Level + value: None WarningsAsErrors: '' HeaderFilterRegex: '.*' diff --git a/README.md b/README.md index bfa8281..77a5e6b 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,95 @@ # PMClassifier - +用于计算Extrusion体在空间查询点处的SDF +## Extrusion体描述 +- 沿多段线路径拉伸 +```C++ +class ExtrudedSolidPolyline { + /** + * @brief Construct a new extruded solid using a polyline as the axis + * @param profiles The profiles of the extruded solid + * @param axis The axis of the extruded solid + * @param rScale The radius scale of the extruded solid, unused for now + */ + ExtrudedSolidPolyline(std::vector profiles, Polyline axis, real rScale = 1.0); +} +``` +- 沿单段线路径拉伸 +```C++ +class ExtrudeSolidArcLine : public ExtrudedSolidPolyline { +public: + /** + * @brief Construct a new extruded solid using an arc line as the axis + * @param profiles The profiles of the extruded solid + * @param axis The axis of the extruded solid + * @param rScale The radius scale of the extruded solid, unused for now + */ + ExtrudeSolidArcLine(std::vector profiles, ArcLine axis, real rScale = 1.0); +}; +``` +- 沿螺旋路径拉伸 +```C++ +class ExtrudedSolidHelixLine { +public: + /** + * @brief Construct a new extruded solid using a helix as the axis + * @param profiles The profiles of the extruded solid (still polyline) + * @param axis The axis of the extruded solid + * @param rScale The radius scale of the extruded solid, unused for now + */ + ExtrudedSolidHelixLine(std::vector profiles, HelixLine axis, real rScale = 1.0); +}; +``` +## 曲线描述 +- 多段线 +```C++ +using Pt3Array = std::vector; +class Polyline { +public: + /** + * @brief Construct a new Polyline object + * @param points The points of the polyline + * @param bugles The bugles of the polyline + * @param refNormal The reference normal of the polyline + * @param closed Whether the polyline is closed + */ + Polyline(Pt3Array points, std::vector bugles, const Vec3 &refNormal, bool closed = false); +} +``` +- 单段线/圆弧线 +```C++ +class ArcLine : public Polyline { +public: + /** + * @brief Construct a new ArcLine object + * @param a The start point of the arc line + * @param b The end point of the arc line + * @param bugle The bugle of the arc line + * @param refNormal The reference normal of the arc line + */ + ArcLine(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal); +}; +``` +- 螺旋线 +```C++ +class HelixLine : public ILine { +public: + /** + * @brief Construct a new HelixLine object + * @param axisStart The start point of the helix line + * @param axisEnd The end point of the helix line + * @param r The radius of the helix line + * @param advancePerRound The advance per round of the helix line + * @param startDir The direction from axisStart to start of the helix line + */ + HelixLine(const Vec3 &axisStart, const Vec3 &axisEnd, real r, real advancePerRound, + const Vec3 &startDir); +} +``` +## 距离查询 +对拉伸体对象使用.sdf(Vec3 queryPoint) +```C++ +Polyline axis{...}; +ExtrudedSolidPolyline a{..., axis}; +const Vec3 queryP = Vec3(...); +auto f = a.sdf(queryP); +``` \ No newline at end of file diff --git a/include/line.hpp b/include/line.hpp index 0c4dd78..55a05f6 100644 --- a/include/line.hpp +++ b/include/line.hpp @@ -39,6 +39,11 @@ class ILine { public: int aaa; virtual ~ILine() = default; + ILine() = default; + ILine(const ILine &) = default; + ILine &operator=(const ILine &) = default; + ILine(ILine &&) = default; + ILine &operator=(ILine &&) = default; virtual Vec3 eval(real t) = 0; @@ -55,6 +60,20 @@ public: [[nodiscard]] virtual bool isEndParam(real t) const = 0; }; +inline static ClosestDescOnSeg segPtDist(const Vec3 &p, const Vec3 &A, const Vec3 &B) { + Vec3 AB = B - A; + Vec3 AP = p - A; + real h = std::clamp(AP.dot(AB) / AB.dot(AB), 0., 1.); + return {h, (AP - AB * h).norm()}; +} + +inline static ClosestDescOnSeg segPtDist(const Vec2 &p, const Vec2 &A, const Vec2 &B) { + Vec2 AB = B - A; + Vec2 AP = p - A; + real h = std::clamp(AP.dot(AB) / AB.dot(AB), 0., 1.); + return {h, (AP - AB * h).norm()}; +} + template // Vec2 or Vec3 struct CircularArc { VecType center; @@ -64,7 +83,7 @@ struct CircularArc { VecType u; VecType v; VecType inCircleDir; - PtBoundaryRelation inCircleCheck(const VecType &pt) const { + [[nodiscard]] PtBoundaryRelation inCircleCheck(const VecType &pt) const { real d = (pt - center).norm(); return d < radius ? Inside : d > radius ? Outside : OnBoundary; } @@ -79,37 +98,6 @@ struct AA { const real DISC_ARC_ANGLE = std::numbers::pi * 0.125; -namespace detail { -void initCircularArcInfo(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal, - CircularArc &res) { - if (isEqual(bugle, 0)) { - res.radius = INFINITY; - res.theta = 0; - res.h = INFINITY; - res.inCircleDir = refNormal.cross(b - a).normalize(); - res.u = res.inCircleDir; - res.v = refNormal.cross(res.u); - return; - } - - Vec3 abHalf = (b - a) * HALF; - Vec3 abNorm = abHalf.normalize(); - real theta = std::atan(fabs(bugle)) * 4; - res.inCircleDir = abNorm.cross(refNormal) * (bugle > 0 ? 1 : -1); - - if (fabs(bugle) == 1) { - res.h = 0; - } else { - res.h = abHalf.norm() / std::tan(theta * HALF); - } - res.center = a + abHalf - res.inCircleDir * res.h; - res.theta = theta; - res.radius = (res.center - a).norm(); - res.u = (a - res.center).normalize(); - res.v = refNormal.cross(res.u); -} -} // namespace detail - class Polyline : public ILine { public: Polyline(Pt3Array points, std::vector bugles, const Vec3 &refNormal, bool closed = false) @@ -136,19 +124,18 @@ public: return circularArcs; } -private: +protected: Pt3Array _points; std::vector _bugles; Vec3 _refNormal; bool _closed; - std::vector> circularArcs; public: void initSegInfo() { for (size_t i = 0; i < _bugles.size(); ++i) { - detail::initCircularArcInfo(_points[i], _points[(i + 1) % _points.size()], _bugles[i], - _refNormal, circularArcs[i]); + initCircularArcInfo(_points[i], _points[(i + 1) % _points.size()], _bugles[i], + _refNormal, circularArcs[i]); } } @@ -332,23 +319,40 @@ public: } std::cout << "}\n"; } - static ClosestDescOnSeg segPtDist(const Vec3 &p, const Vec3 &A, const Vec3 &B) { - Vec3 AB = B - A; - Vec3 AP = p - A; - real h = std::clamp(AP.dot(AB) / AB.dot(AB), 0., 1.); - return {h, (AP - AB * h).norm()}; - } - - static ClosestDescOnSeg segPtDist(const Vec2 &p, const Vec2 &A, const Vec2 &B) { - Vec2 AB = B - A; - Vec2 AP = p - A; - real h = std::clamp(AP.dot(AB) / AB.dot(AB), 0., 1.); - return {h, (AP - AB * h).norm()}; - } [[nodiscard]] bool isEndParam(real t) const override { return t < EPS_END_PARAM || t > static_cast(_bugles.size()) - EPS_END_PARAM; } + +private: + void initCircularArcInfo(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal, + CircularArc &res) { + if (isEqual(bugle, 0)) { + res.radius = INFINITY; + res.theta = 0; + res.h = INFINITY; + res.inCircleDir = refNormal.cross(b - a).normalize(); + res.u = res.inCircleDir; + res.v = refNormal.cross(res.u); + return; + } + + Vec3 abHalf = (b - a) * HALF; + Vec3 abNorm = abHalf.normalize(); + real theta = std::atan(fabs(bugle)) * 4; + res.inCircleDir = abNorm.cross(refNormal) * (bugle > 0 ? 1 : -1); + + if (fabs(bugle) == 1) { + res.h = 0; + } else { + res.h = abHalf.norm() / std::tan(theta * HALF); + } + res.center = a + abHalf - res.inCircleDir * res.h; + res.theta = theta; + res.radius = (res.center - a).norm(); + res.u = (a - res.center).normalize(); + res.v = refNormal.cross(res.u); + } }; class HelixLine : public ILine { @@ -481,27 +485,19 @@ public: }; // 单段圆弧 -// 其实就是 -class ArcLine : public ILine { +class ArcLine : public Polyline { public: ArcLine(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal) - : _a(a), _b(b), _bugle(bugle), _refNormal(refNormal.normalize()) {} - - bool isEndParam(real t) const override { return t < EPS || t > 1 - EPS; } - Vec3 eval(real t) override { return {}; }; - - Vec3 der1(real t) override { return {}; }; - - Vec3 der2(real t) override { return {}; }; - + // : _a(a), _b(b), _bugle(bugle), _refNormal(refNormal.normalize()) {} + : Polyline(Pt3Array{{a, b}}, std::vector{bugle}, refNormal, false) {} ClosestDescOnSeg getClosestParam(const Vec3 &p) override { return {}; }; + [[nodiscard]] const std::vector &getBugles() const = delete; + [[nodiscard]] const real &getBugle() const { return _bugles[0]; } -private: - Vec3 _a, _b, _refNormal; - real _bugle; - CircularArc _circularArc; - - void initArcInfo() { detail::initCircularArcInfo(_a, _b, _bugle, _refNormal, _circularArc); } + // private: + // Vec3 _a, _b, _refNormal; + // real _bugle; + // CircularArc _circularArc; }; class PolynomialLine : public ILine { diff --git a/include/solid.hpp b/include/solid.hpp index aa0a1fa..51b0e43 100644 --- a/include/solid.hpp +++ b/include/solid.hpp @@ -50,6 +50,8 @@ protected: std::vector _localProfiles2D; std::vector>> _localArcs2d; Vec3 _biNormalStartPt; + +public: IExtrudedSolidBase(std::vector profiles, AxisLineType axis, real rScale) : ISolid(), _profiles(std::move(profiles)), _axis(std::move(axis)), _rScale(rScale) { assert(!_profiles.empty()); @@ -263,6 +265,9 @@ private: static ClosestDescOnSeg distance2Arc2D(const Vec2 &p2D, const Vec2 &a, const Vec2 &b, const CircularArc &arc) { + if (isEqual(arc.theta, 0)) { + return segPtDist(p2D, a, b); + } const Vec2 ¢er = arc.center; Vec2 op = p2D - center; Vec2 q = center + arc.radius * op.normalize(); // closest pt on circle @@ -370,6 +375,12 @@ public: // } }; +class ExtrudeSolidArcLine : public ExtrudedSolidPolyline { +public: + ExtrudeSolidArcLine(std::vector profiles, ArcLine axis, real rScale = 1.0) + : ExtrudedSolidPolyline(std::move(profiles), std::move(axis), rScale) {} +}; + class ExtrudedSolidHelixLine : public IExtrudedSolidBase { public: ExtrudedSolidHelixLine(std::vector profiles, HelixLine axis, real rScale = 1.0) diff --git a/main.cpp b/main.cpp index 69ea093..aee7ee7 100644 --- a/main.cpp +++ b/main.cpp @@ -4,18 +4,10 @@ // TIP To Run code, press or // click the icon in the gutter. int main() { - // TIP Press when your caret is at the - // lang variable name to see how CLion can help you rename it. - auto lang = "C++"; - std::cout << "Hello and welcome to " << lang << "!\n"; - - for (int i = 1; i <= 5; i++) { - // TIP Press to start debugging your code. - // We have set one - // breakpoint for you, but you can always add more by pressing - // . - std::cout << "i = " << i << std::endl; - } + Polyline axis{{}, {}, Vec3()}; + ExtrudedSolidPolyline a({axis}, axis); + const Vec3 queryP = Vec3(); + auto f = a.sdf(queryP); return 0; }