Browse Source

single arc line & readme doc

master
gjj 4 months ago
parent
commit
5daa507686
  1. 3
      .clang-tidy
  2. 95
      README.md
  3. 124
      include/line.hpp
  4. 11
      include/solid.hpp
  5. 16
      main.cpp

3
.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: '.*'

95
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<Polyline> 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<Polyline> 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<Polyline> profiles, HelixLine axis, real rScale = 1.0);
};
```
## 曲线描述
- 多段线
```C++
using Pt3Array = std::vector<Vec3>;
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<real> 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);
```

124
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 <typename VecType> // 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<Vec3> &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<real> bugles, const Vec3 &refNormal, bool closed = false)
@ -136,18 +124,17 @@ public:
return circularArcs;
}
private:
protected:
Pt3Array _points;
std::vector<real> _bugles;
Vec3 _refNormal;
bool _closed;
std::vector<CircularArc<Vec3>> circularArcs;
public:
void initSegInfo() {
for (size_t i = 0; i < _bugles.size(); ++i) {
detail::initCircularArcInfo(_points[i], _points[(i + 1) % _points.size()], _bugles[i],
initCircularArcInfo(_points[i], _points[(i + 1) % _points.size()], _bugles[i],
_refNormal, circularArcs[i]);
}
}
@ -332,22 +319,39 @@ 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()};
[[nodiscard]] bool isEndParam(real t) const override {
return t < EPS_END_PARAM || t > static_cast<real>(_bugles.size()) - EPS_END_PARAM;
}
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()};
private:
void initCircularArcInfo(const Vec3 &a, const Vec3 &b, real bugle, const Vec3 &refNormal,
CircularArc<Vec3> &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;
}
[[nodiscard]] bool isEndParam(real t) const override {
return t < EPS_END_PARAM || t > static_cast<real>(_bugles.size()) - EPS_END_PARAM;
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);
}
};
@ -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<real>{bugle}, refNormal, false) {}
ClosestDescOnSeg getClosestParam(const Vec3 &p) override { return {}; };
[[nodiscard]] const std::vector<real> &getBugles() const = delete;
[[nodiscard]] const real &getBugle() const { return _bugles[0]; }
private:
Vec3 _a, _b, _refNormal;
real _bugle;
CircularArc<Vec3> _circularArc;
void initArcInfo() { detail::initCircularArcInfo(_a, _b, _bugle, _refNormal, _circularArc); }
// private:
// Vec3 _a, _b, _refNormal;
// real _bugle;
// CircularArc<Vec3> _circularArc;
};
class PolynomialLine : public ILine {

11
include/solid.hpp

@ -50,6 +50,8 @@ protected:
std::vector<Pt2Array> _localProfiles2D;
std::vector<std::vector<CircularArc<Vec2>>> _localArcs2d;
Vec3 _biNormalStartPt;
public:
IExtrudedSolidBase(std::vector<Polyline> 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<Vec2> &arc) {
if (isEqual(arc.theta, 0)) {
return segPtDist(p2D, a, b);
}
const Vec2 &center = 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<Polyline> profiles, ArcLine axis, real rScale = 1.0)
: ExtrudedSolidPolyline(std::move(profiles), std::move(axis), rScale) {}
};
class ExtrudedSolidHelixLine : public IExtrudedSolidBase<HelixLine> {
public:
ExtrudedSolidHelixLine(std::vector<Polyline> profiles, HelixLine axis, real rScale = 1.0)

16
main.cpp

@ -4,18 +4,10 @@
// TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
int main() {
// TIP Press <shortcut actionId="RenameElement"/> when your caret is at the
// <b>lang</b> 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 <shortcut actionId="Debug"/> to start debugging your code.
// We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/>
// breakpoint for you, but you can always add more by pressing
// <shortcut actionId="ToggleLineBreakpoint"/>.
std::cout << "i = " << i << std::endl;
}
Polyline axis{{}, {}, Vec3()};
ExtrudedSolidPolyline a({axis}, axis);
const Vec3 queryP = Vec3();
auto f = a.sdf(queryP);
return 0;
}

Loading…
Cancel
Save