Sketcher: Fix: Arc of Hyperbola (#27656)
* Sketcher: Fix: Arc of Hyperbola * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added minor grater than major radius support * Fixed merge errors * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Improved comments and added a confused points check for S1 and S2 distance. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Added compile check for occ version and check before getting minor radius. * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Apply suggestions from code review OCC version check Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org> --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Chris Hennes <chennes@pioneerlibrarysystem.org>
This commit is contained in:
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <GC_MakeHyperbola.hxx>
|
||||
#include <Geom_Hyperbola.hxx>
|
||||
|
||||
#include <Standard_Version.hxx>
|
||||
|
||||
#include <Base/GeometryPyCXX.h>
|
||||
#include <Base/PyWrapParseTupleAndKeywords.h>
|
||||
@@ -97,11 +97,39 @@ int HyperbolaPy::PyInit(PyObject* args, PyObject* kwds)
|
||||
Base::Vector3d v1 = static_cast<Base::VectorPy*>(pV1)->value();
|
||||
Base::Vector3d v2 = static_cast<Base::VectorPy*>(pV2)->value();
|
||||
Base::Vector3d v3 = static_cast<Base::VectorPy*>(pV3)->value();
|
||||
|
||||
|
||||
#if OCC_VERSION_HEX < 0x080000
|
||||
// This is a workaround do to fault in OCCT.
|
||||
// It is fixed in OCCT 8.0.0,
|
||||
gp_Pnt S1(v1.x, v1.y, v1.z);
|
||||
gp_Pnt S2(v2.x, v2.y, v2.z);
|
||||
gp_Pnt Center(v3.x, v3.y, v3.z);
|
||||
|
||||
if (S1.Distance(Center) < gp::Resolution() || S2.Distance(Center) < gp::Resolution()
|
||||
|| S1.Distance(S2) < gp::Resolution()) {
|
||||
PyErr_SetString(PartExceptionOCCError, gce_ErrorStatusText(gce_ConfusedPoints));
|
||||
return -1;
|
||||
}
|
||||
|
||||
gp_Dir XAxis(S1.XYZ() - Center.XYZ());
|
||||
gp_Lin centerLine(Center, XAxis);
|
||||
double majorRadius = S1.Distance(Center);
|
||||
double minorRadius = centerLine.Distance(S2);
|
||||
if (minorRadius < gp::Resolution()) {
|
||||
PyErr_SetString(PartExceptionOCCError, gce_ErrorStatusText(gce_ColinearPoints));
|
||||
return -1;
|
||||
}
|
||||
gp_Dir norm(XAxis.Crossed(gp_Dir(S2.XYZ() - Center.XYZ())));
|
||||
GC_MakeHyperbola me(gp_Ax2(Center, norm, XAxis), majorRadius, minorRadius);
|
||||
#else
|
||||
GC_MakeHyperbola me(
|
||||
gp_Pnt(v1.x, v1.y, v1.z),
|
||||
gp_Pnt(v2.x, v2.y, v2.z),
|
||||
gp_Pnt(v3.x, v3.y, v3.z)
|
||||
);
|
||||
#endif
|
||||
|
||||
if (!me.IsDone()) {
|
||||
PyErr_SetString(PartExceptionOCCError, gce_ErrorStatusText(me.Status()));
|
||||
return -1;
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
|
||||
#include <Gui/Notifications.h>
|
||||
#include <Gui/Command.h>
|
||||
#include <Gui/CommandT.h>
|
||||
@@ -51,31 +49,30 @@ class DrawSketchHandlerArcOfHyperbola: public DrawSketchHandler
|
||||
|
||||
public:
|
||||
DrawSketchHandlerArcOfHyperbola()
|
||||
: Mode(STATUS_SEEK_First)
|
||||
: Mode(SelectMode::First)
|
||||
, EditCurve(34)
|
||||
, arcAngle(0)
|
||||
, arcAngle_t(0)
|
||||
{}
|
||||
|
||||
~DrawSketchHandlerArcOfHyperbola() override = default;
|
||||
/// mode table
|
||||
enum SelectMode
|
||||
enum class SelectMode
|
||||
{
|
||||
STATUS_SEEK_First,
|
||||
STATUS_SEEK_Second,
|
||||
STATUS_SEEK_Third,
|
||||
STATUS_SEEK_Fourth,
|
||||
STATUS_Close
|
||||
First,
|
||||
Second,
|
||||
Third,
|
||||
Fourth,
|
||||
End
|
||||
};
|
||||
|
||||
void mouseMove(SnapManager::SnapHandle snapHandle) override
|
||||
{
|
||||
Base::Vector2d onSketchPos = snapHandle.compute();
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
if (Mode == SelectMode::First) {
|
||||
setPositionText(onSketchPos);
|
||||
seekAndRenderAutoConstraint(sugConstr1, onSketchPos, Base::Vector2d(0.f, 0.f));
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_Second) {
|
||||
else if (Mode == SelectMode::Second) {
|
||||
EditCurve[1] = onSketchPos;
|
||||
|
||||
// Display radius for user
|
||||
@@ -95,103 +92,115 @@ public:
|
||||
AutoConstraint::CURVE
|
||||
);
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_Third) {
|
||||
else if (Mode == SelectMode::Third) {
|
||||
// angle between the major axis of the hyperbola and the X axis
|
||||
double a = (axisPoint - centerPoint).Length();
|
||||
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
|
||||
Base::Vector2d delta12 = axisPoint - centerPoint;
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatpoint = acosh(
|
||||
((onSketchPos.x - centerPoint.x) * cos(phi)
|
||||
+ (onSketchPos.y - centerPoint.y) * sin(phi))
|
||||
/ a
|
||||
double a = delta12.Length();
|
||||
assert(
|
||||
a > Precision::Confusion()
|
||||
&& "DrawSketchHandlerArcOfHyperbola: First and second point are at the same place"
|
||||
);
|
||||
double b = ((onSketchPos.y - centerPoint.y) * cos(phi)
|
||||
- (onSketchPos.x - centerPoint.x) * sin(phi))
|
||||
/ sinh(angleatpoint);
|
||||
|
||||
if (!boost::math::isnan(b)) {
|
||||
for (int i = 15; i >= -15; i--) {
|
||||
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
|
||||
// double angle = i*std::numbers::pi/16.0;
|
||||
double angle = i * angleatpoint / 15;
|
||||
double rx = a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi);
|
||||
double ry = a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi);
|
||||
EditCurve[15 + i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
|
||||
}
|
||||
Base::Vector2d aDir = delta12.Normalize();
|
||||
Base::Vector2d bDir(-aDir.y, aDir.x);
|
||||
|
||||
// Display radius for user
|
||||
if (showCursorCoords()) {
|
||||
SbString text;
|
||||
std::string aString = lengthToDisplayFormat(a, 1);
|
||||
std::string bString = lengthToDisplayFormat(b, 1);
|
||||
text.sprintf(" (R%s, R%s)", aString.c_str(), bString.c_str());
|
||||
setPositionText(onSketchPos, text);
|
||||
}
|
||||
Base::Vector2d delta13 = onSketchPos - centerPoint;
|
||||
Base::Vector2d delta13Prime(
|
||||
delta13.x * aDir.x + delta13.y * aDir.y,
|
||||
delta13.x * bDir.x + delta13.y * bDir.y
|
||||
);
|
||||
|
||||
drawEdit(EditCurve);
|
||||
seekAndRenderAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f));
|
||||
// 0 if less than Precision::Confusion()
|
||||
double b = getMinorRadius(onSketchPos);
|
||||
|
||||
double angleatpoint = 0;
|
||||
if (b != 0) {
|
||||
angleatpoint = atanh((delta13Prime.y * a) / (delta13Prime.x * b));
|
||||
}
|
||||
|
||||
for (int i = 16; i >= -16; i--) {
|
||||
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
|
||||
double angle = i * angleatpoint / 16.0;
|
||||
double rx = a * cosh(angle) * aDir.x + b * sinh(angle) * bDir.x;
|
||||
double ry = a * cosh(angle) * aDir.y + b * sinh(angle) * bDir.y;
|
||||
EditCurve[16 + i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
|
||||
}
|
||||
|
||||
// Display radius for user
|
||||
if (showCursorCoords()) {
|
||||
SbString text;
|
||||
std::string aString = lengthToDisplayFormat(a, 1);
|
||||
std::string bString = lengthToDisplayFormat(b, 1);
|
||||
text.sprintf(" (R%s, R%s)", aString.c_str(), bString.c_str());
|
||||
setPositionText(onSketchPos, text);
|
||||
}
|
||||
|
||||
if (b != 0) {
|
||||
drawEdit(EditCurve);
|
||||
}
|
||||
else {
|
||||
drawEdit(std::vector<Base::Vector2d>());
|
||||
}
|
||||
|
||||
seekAndRenderAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f, 0.f));
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_Fourth) {
|
||||
else if (Mode == SelectMode::Fourth) {
|
||||
// angle between the major axis of the hyperbola and the X axis
|
||||
double a = (axisPoint - centerPoint).Length();
|
||||
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
|
||||
Base::Vector2d delta12 = axisPoint - centerPoint;
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatstartingpoint = acosh(
|
||||
((startingPoint.x - centerPoint.x) * cos(phi)
|
||||
+ (startingPoint.y - centerPoint.y) * sin(phi))
|
||||
/ a
|
||||
);
|
||||
double b = ((startingPoint.y - centerPoint.y) * cos(phi)
|
||||
- (startingPoint.x - centerPoint.x) * sin(phi))
|
||||
/ sinh(angleatstartingpoint);
|
||||
|
||||
double startAngle = angleatstartingpoint;
|
||||
|
||||
// double angleatpoint =
|
||||
// acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
|
||||
|
||||
double angleatpoint = atanh(
|
||||
(((onSketchPos.y - centerPoint.y) * cos(phi)
|
||||
- (onSketchPos.x - centerPoint.x) * sin(phi))
|
||||
* a)
|
||||
/ (((onSketchPos.x - centerPoint.x) * cos(phi)
|
||||
+ (onSketchPos.y - centerPoint.y) * sin(phi))
|
||||
* b)
|
||||
double a = delta12.Length();
|
||||
assert(
|
||||
a > Precision::Confusion()
|
||||
&& "DrawSketchHandlerArcOfHyperbola: First and second point are at the same place"
|
||||
);
|
||||
|
||||
/*double angle1 = angleatpoint - startAngle;
|
||||
Base::Vector2d aDir = delta12.Normalize();
|
||||
Base::Vector2d bDir(-aDir.y, aDir.x);
|
||||
|
||||
double angle2 = angle1 + (angle1 < 0. ? 2 : -2) * std::numbers::pi ;
|
||||
arcAngle = abs(angle1-arcAngle) < abs(angle2-arcAngle) ? angle1 : angle2;*/
|
||||
Base::Vector2d delta13 = startingPoint - centerPoint;
|
||||
Base::Vector2d delta13Prime(
|
||||
delta13.x * aDir.x + delta13.y * aDir.y,
|
||||
delta13.x * bDir.x + delta13.y * bDir.y
|
||||
);
|
||||
|
||||
double b = getMinorRadius(startingPoint);
|
||||
assert(
|
||||
b > Precision::Confusion() && "DrawSketchHandlerArcOfHyperbola: Minor radius was unexpectedly set to invalid value"
|
||||
);
|
||||
|
||||
double startAngle = atanh((delta13Prime.y * a) / (delta13Prime.x * b));
|
||||
|
||||
Base::Vector2d delta14 = onSketchPos - centerPoint;
|
||||
Base::Vector2d delta14Prime(
|
||||
delta14.x * aDir.x + delta14.y * aDir.y,
|
||||
delta14.x * bDir.x + delta14.y * bDir.y
|
||||
);
|
||||
|
||||
double angleatpoint = atanh((delta14Prime.y * a) / (delta14Prime.x * b));
|
||||
|
||||
arcAngle = angleatpoint - startAngle;
|
||||
|
||||
// if(!boost::math::isnan(angle1) && !boost::math::isnan(angle2)){
|
||||
if (!boost::math::isnan(arcAngle)) {
|
||||
EditCurve.resize(33);
|
||||
for (int i = 0; i < 33; i++) {
|
||||
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
|
||||
// double angle=i*angleatpoint/16;
|
||||
double angle = startAngle + i * arcAngle / 32.0;
|
||||
double rx = a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi);
|
||||
double ry = a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi);
|
||||
EditCurve[i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
|
||||
}
|
||||
|
||||
// Display radius for user
|
||||
if (showCursorCoords()) {
|
||||
SbString text;
|
||||
std::string aString = lengthToDisplayFormat(a, 1);
|
||||
std::string bString = lengthToDisplayFormat(b, 1);
|
||||
text.sprintf(" (R%s, R%s)", aString.c_str(), bString.c_str());
|
||||
setPositionText(onSketchPos, text);
|
||||
}
|
||||
if (std::abs((delta14Prime.y * a) / (delta14Prime.x * b)) > 1) {
|
||||
arcAngle = 0;
|
||||
}
|
||||
else {
|
||||
arcAngle = 0.;
|
||||
|
||||
for (int i = 0; i < 33; i++) {
|
||||
// P(U) = O + MajRad*Cosh(U)*XDir + MinRad*Sinh(U)*YDir
|
||||
double angle = startAngle + i * arcAngle / 32.0;
|
||||
double rx = a * cosh(angle) * aDir.x + b * sinh(angle) * bDir.x;
|
||||
double ry = a * cosh(angle) * aDir.y + b * sinh(angle) * bDir.y;
|
||||
EditCurve[i] = Base::Vector2d(centerPoint.x + rx, centerPoint.y + ry);
|
||||
}
|
||||
|
||||
// Display radius for user
|
||||
if (showCursorCoords()) {
|
||||
SbString text;
|
||||
std::string aString = lengthToDisplayFormat(a, 1);
|
||||
std::string bString = lengthToDisplayFormat(b, 1);
|
||||
std::string arcAngleString = angleToDisplayFormat(Base::toDegrees(arcAngle), 1);
|
||||
text.sprintf(" (R%s, R%s, %s)", aString.c_str(), bString.c_str(), arcAngleString.c_str());
|
||||
setPositionText(onSketchPos, text);
|
||||
}
|
||||
|
||||
drawEdit(EditCurve);
|
||||
@@ -201,28 +210,28 @@ public:
|
||||
|
||||
bool pressButton(Base::Vector2d onSketchPos) override
|
||||
{
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
if (Mode == SelectMode::First) {
|
||||
EditCurve[0] = onSketchPos;
|
||||
centerPoint = onSketchPos;
|
||||
EditCurve.resize(2);
|
||||
Mode = STATUS_SEEK_Second;
|
||||
Mode = SelectMode::Second;
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_Second) {
|
||||
else if (Mode == SelectMode::Second
|
||||
&& (centerPoint - onSketchPos).Length() > Precision::Confusion()) {
|
||||
EditCurve[1] = onSketchPos;
|
||||
axisPoint = onSketchPos;
|
||||
EditCurve.resize(31);
|
||||
Mode = STATUS_SEEK_Third;
|
||||
EditCurve.resize(33);
|
||||
Mode = SelectMode::Third;
|
||||
}
|
||||
else if (Mode == STATUS_SEEK_Third) {
|
||||
else if (Mode == SelectMode::Third && getMinorRadius(onSketchPos) > Precision::Confusion()) {
|
||||
startingPoint = onSketchPos;
|
||||
arcAngle = 0.;
|
||||
arcAngle_t = 0.;
|
||||
Mode = STATUS_SEEK_Fourth;
|
||||
Mode = SelectMode::Fourth;
|
||||
}
|
||||
else { // Fourth
|
||||
else if (Mode == SelectMode::Fourth && arcAngle != 0) {
|
||||
endPoint = onSketchPos;
|
||||
|
||||
Mode = STATUS_Close;
|
||||
Mode = SelectMode::End;
|
||||
}
|
||||
|
||||
updateHint();
|
||||
@@ -231,88 +240,47 @@ public:
|
||||
|
||||
bool releaseButton(Base::Vector2d /*onSketchPos*/) override
|
||||
{
|
||||
if (Mode == STATUS_Close) {
|
||||
if (Mode == SelectMode::End) {
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
|
||||
Base::Vector2d delta12 = axisPoint - centerPoint;
|
||||
|
||||
// angle between the major axis of the hyperbola and the X axis
|
||||
double a = (axisPoint - centerPoint).Length();
|
||||
double phi = atan2(axisPoint.y - centerPoint.y, axisPoint.x - centerPoint.x);
|
||||
double a = delta12.Length();
|
||||
|
||||
// This is the angle at cursor point
|
||||
double angleatstartingpoint = acosh(
|
||||
((startingPoint.x - centerPoint.x) * cos(phi)
|
||||
+ (startingPoint.y - centerPoint.y) * sin(phi))
|
||||
/ a
|
||||
Base::Vector2d aDir = delta12.Normalize();
|
||||
Base::Vector2d bDir(-aDir.y, aDir.x);
|
||||
|
||||
Base::Vector2d delta13 = startingPoint - centerPoint;
|
||||
Base::Vector2d delta13Prime(
|
||||
delta13.x * aDir.x + delta13.y * aDir.y,
|
||||
delta13.x * bDir.x + delta13.y * bDir.y
|
||||
);
|
||||
|
||||
double b = ((startingPoint.y - centerPoint.y) * cos(phi)
|
||||
- (startingPoint.x - centerPoint.x) * sin(phi))
|
||||
/ sinh(angleatstartingpoint);
|
||||
double b = getMinorRadius(startingPoint);
|
||||
|
||||
double startAngle = angleatstartingpoint;
|
||||
double startAngle = atanh((delta13Prime.y * a) / (delta13Prime.x * b));
|
||||
|
||||
// double angleatpoint =
|
||||
// acosh(((onSketchPos.x-centerPoint.x)*cos(phi)+(onSketchPos.y-centerPoint.y)*sin(phi))/a);
|
||||
|
||||
double endAngle = atanh(
|
||||
(((endPoint.y - centerPoint.y) * cos(phi) - (endPoint.x - centerPoint.x) * sin(phi))
|
||||
* a)
|
||||
/ (((endPoint.x - centerPoint.x) * cos(phi) + (endPoint.y - centerPoint.y) * sin(phi))
|
||||
* b)
|
||||
Base::Vector2d delta14 = endPoint - centerPoint;
|
||||
Base::Vector2d delta14Prime(
|
||||
delta14.x * aDir.x + delta14.y * aDir.y,
|
||||
delta14.x * bDir.x + delta14.y * bDir.y
|
||||
);
|
||||
|
||||
if (boost::math::isnan(startAngle) || boost::math::isnan(endAngle)) {
|
||||
Gui::NotifyError(
|
||||
sketchgui,
|
||||
QT_TRANSLATE_NOOP("Notifications", "Error"),
|
||||
QT_TRANSLATE_NOOP(
|
||||
"Notifications",
|
||||
"Cannot create arc of hyperbola from invalid angles, try again!"
|
||||
)
|
||||
);
|
||||
sketchgui->purgeHandler();
|
||||
return false;
|
||||
}
|
||||
|
||||
double endAngle = atanh((delta14Prime.y * a) / (delta14Prime.x * b));
|
||||
|
||||
bool isOriginalArcCCW = true;
|
||||
|
||||
if (arcAngle > 0) {
|
||||
endAngle = startAngle + arcAngle;
|
||||
}
|
||||
else {
|
||||
endAngle = startAngle;
|
||||
startAngle += arcAngle;
|
||||
if (endAngle < startAngle) {
|
||||
std::swap(startAngle, endAngle);
|
||||
isOriginalArcCCW = false;
|
||||
}
|
||||
|
||||
Base::Vector2d majAxisDir, minAxisDir, minAxisPoint, majAxisPoint;
|
||||
Base::Vector2d minAxisPoint, majAxisPoint;
|
||||
// We always create a CCW hyperbola, because we want our XY reference system to be in
|
||||
// the +X +Y direction Our normal will then always be in the +Z axis (local +Z axis of
|
||||
// the sketcher)
|
||||
|
||||
if (a > b) {
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
majAxisDir = axisPoint - centerPoint;
|
||||
Base::Vector2d perp(-majAxisDir.y, majAxisDir.x);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
minAxisPoint = centerPoint + perp;
|
||||
majAxisPoint = centerPoint + majAxisDir;
|
||||
}
|
||||
else {
|
||||
// force second semidiameter to be perpendicular to first semidiamater
|
||||
minAxisDir = axisPoint - centerPoint;
|
||||
Base::Vector2d perp(minAxisDir.y, -minAxisDir.x);
|
||||
perp.Normalize();
|
||||
perp.Scale(abs(b));
|
||||
majAxisPoint = centerPoint + perp;
|
||||
minAxisPoint = centerPoint + minAxisDir;
|
||||
endAngle += std::numbers::pi / 2;
|
||||
startAngle += std::numbers::pi / 2;
|
||||
}
|
||||
majAxisPoint = centerPoint + (aDir * a);
|
||||
minAxisPoint = centerPoint + (bDir * b);
|
||||
|
||||
int currentgeoid = getHighestCurveIndex();
|
||||
|
||||
@@ -399,7 +367,7 @@ public:
|
||||
|
||||
if (continuousMode) {
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
Mode = SelectMode::First;
|
||||
EditCurve.clear();
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(34);
|
||||
@@ -431,22 +399,22 @@ private:
|
||||
return Gui::lookupHints<SelectMode>(
|
||||
Mode,
|
||||
{
|
||||
{.state = STATUS_SEEK_First,
|
||||
{.state = SelectMode::First,
|
||||
.hints =
|
||||
{
|
||||
{tr("%1 pick center point"), {MouseLeft}},
|
||||
}},
|
||||
{.state = STATUS_SEEK_Second,
|
||||
{.state = SelectMode::Second,
|
||||
.hints =
|
||||
{
|
||||
{tr("%1 pick axis point"), {MouseLeft}},
|
||||
}},
|
||||
{.state = STATUS_SEEK_Third,
|
||||
{.state = SelectMode::Third,
|
||||
.hints =
|
||||
{
|
||||
{tr("%1 pick arc start point"), {MouseLeft}},
|
||||
}},
|
||||
{.state = STATUS_SEEK_Fourth,
|
||||
{.state = SelectMode::Fourth,
|
||||
.hints =
|
||||
{
|
||||
{tr("%1 pick arc end point"), {MouseLeft}},
|
||||
@@ -454,11 +422,33 @@ private:
|
||||
});
|
||||
}
|
||||
|
||||
double getMinorRadius(const Base::Vector2d& onSketchPos)
|
||||
{
|
||||
Base::Vector2d delta12 = axisPoint - centerPoint;
|
||||
|
||||
double a = delta12.Length();
|
||||
|
||||
Base::Vector2d aDir = delta12.Normalize();
|
||||
Base::Vector2d bDir(-aDir.y, aDir.x);
|
||||
|
||||
Base::Vector2d delta13 = onSketchPos - centerPoint;
|
||||
Base::Vector2d delta13Prime(
|
||||
delta13.x * aDir.x + delta13.y * aDir.y,
|
||||
delta13.x * bDir.x + delta13.y * bDir.y
|
||||
);
|
||||
|
||||
double denom = (delta13Prime.x * delta13Prime.x) / (a * a) - 1.0;
|
||||
if (denom <= Precision::Confusion()) {
|
||||
return 0;
|
||||
}
|
||||
return std::sqrt((delta13Prime.y * delta13Prime.y) / denom);
|
||||
}
|
||||
|
||||
protected:
|
||||
SelectMode Mode;
|
||||
std::vector<Base::Vector2d> EditCurve;
|
||||
Base::Vector2d centerPoint, axisPoint, startingPoint, endPoint;
|
||||
double arcAngle, arcAngle_t;
|
||||
double arcAngle;
|
||||
std::vector<AutoConstraint> sugConstr1, sugConstr2, sugConstr3, sugConstr4;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user