This repository has been archived on 2026-05-28. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
DRAwer_2_0/GCS/Constraints.h
Anton Kamalov e613b4f004 Initial commit
2025-12-06 16:01:44 +03:00

1414 lines
37 KiB
C++

/***************************************************************************
* Copyright (c) 2011 Konstantinos Poulios <logari81@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef PLANEGCS_CONSTRAINTS_H
#define PLANEGCS_CONSTRAINTS_H
#include "Geo.h"
// This enables debugging code intended to extract information to file bug reports against Eigen,
// not for production code
// #define _GCS_EXTRACT_SOLVER_SUBSYSTEM_
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
#define _PROTECTED_UNLESS_EXTRACT_MODE_ public
#else
#define _PROTECTED_UNLESS_EXTRACT_MODE_ protected
#endif
namespace GCS
{
///////////////////////////////////////
// Constraints
///////////////////////////////////////
enum ConstraintType
{
None = 0,
Equal = 1,
Difference = 2,
P2PDistance = 3,
P2PAngle = 4,
P2LDistance = 5,
PointOnLine = 6,
PointOnPerpBisector = 7,
Parallel = 8,
Perpendicular = 9,
L2LAngle = 10,
MidpointOnLine = 11,
TangentCircumf = 12,
PointOnEllipse = 13,
TangentEllipseLine = 14,
InternalAlignmentPoint2Ellipse = 15,
EqualMajorAxesConic = 16,
EllipticalArcRangeToEndPoints = 17,
AngleViaPoint = 18,
Snell = 19,
CurveValue = 20,
PointOnHyperbola = 21,
InternalAlignmentPoint2Hyperbola = 22,
PointOnParabola = 23,
EqualFocalDistance = 24,
EqualLineLength = 25,
CenterOfGravity = 26,
WeightedLinearCombination = 27,
SlopeAtBSplineKnot = 28,
PointOnBSpline = 29,
C2CDistance = 30,
C2LDistance = 31,
P2CDistance = 32,
AngleViaPointAndParam = 33,
AngleViaPointAndTwoParams = 34,
AngleViaTwoPoints = 35,
ArcLength = 36,
};
enum InternalAlignmentType
{
EllipsePositiveMajorX = 0,
EllipsePositiveMajorY = 1,
EllipseNegativeMajorX = 2,
EllipseNegativeMajorY = 3,
EllipsePositiveMinorX = 4,
EllipsePositiveMinorY = 5,
EllipseNegativeMinorX = 6,
EllipseNegativeMinorY = 7,
EllipseFocus2X = 8,
EllipseFocus2Y = 9,
HyperbolaPositiveMajorX = 10,
HyperbolaPositiveMajorY = 11,
HyperbolaNegativeMajorX = 12,
HyperbolaNegativeMajorY = 13,
HyperbolaPositiveMinorX = 14,
HyperbolaPositiveMinorY = 15,
HyperbolaNegativeMinorX = 16,
HyperbolaNegativeMinorY = 17
};
class Constraint
{
public:
enum class Alignment
{
NoInternalAlignment,
InternalAlignment
};
_PROTECTED_UNLESS_EXTRACT_MODE_
: VEC_pD origpvec; // is used only as a reference for redirecting and reverting pvec
VEC_pD pvec;
double scale;
int tag;
// indicates that pvec has changed and saved pointers must be reconstructed (currently used only
// in AngleViaPoint)
bool pvecChangedFlag;
bool driving;
Alignment internalAlignment;
public:
Constraint();
virtual ~Constraint()
{}
inline VEC_pD params()
{
return pvec;
}
void redirectParams(const MAP_pD_pD& redirectionmap);
void revertParams();
void setTag(int tagId)
{
tag = tagId;
}
int getTag()
{
return tag;
}
void setDriving(bool isdriving)
{
driving = isdriving;
}
bool isDriving() const
{
return driving;
}
void setInternalAlignment(Alignment isinternalalignment)
{
internalAlignment = isinternalalignment;
}
Alignment isInternalAlignment() const
{
return internalAlignment;
}
virtual ConstraintType getTypeId();
virtual void rescale(double coef = 1.);
virtual double error();
virtual double grad(double*);
// virtual void grad(MAP_pD_D &deriv); --> TODO: vectorized grad version
virtual double maxStep(MAP_pD_D& dir, double lim = 1.);
// Finds first occurrence of param in pvec. This is useful to test if a constraint depends
// on the parameter (it may not actually depend on it, e.g. angle-via-point doesn't depend
// on ellipse's b (radmin), but b will be included within the constraint anyway.
// Returns -1 if not found.
int findParamInPvec(double* param);
};
// Equal
class ConstraintEqual: public Constraint
{
private:
double ratio;
inline double* param1()
{
return pvec[0];
}
inline double* param2()
{
return pvec[1];
}
public:
ConstraintEqual(double* p1, double* p2, double p1p2ratio = 1.0);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// Center of Gravity
class ConstraintCenterOfGravity: public Constraint
{
inline double* thecenter()
{
return pvec[0];
}
inline double* pointat(size_t i)
{
return pvec[1 + i];
}
public:
/// Constrains that the first parameter is center of gravity of rest
/// Let `pvec = [q, p_1, p_2,...]`, and
/// `givenweights = [f_1, f_2,...]`, then this constraint ensures
/// `q = sum(p_i*f_i)`.
ConstraintCenterOfGravity(const std::vector<double*>& givenpvec,
const std::vector<double>& givenweights);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
private:
std::vector<double> weights;
std::size_t numpoints;
};
// Weighted Linear Combination
class ConstraintWeightedLinearCombination: public Constraint
{
inline double* thepoint()
{
return pvec[0];
}
inline double* poleat(size_t i)
{
return pvec[1 + i];
}
inline double* weightat(size_t i)
{
return pvec[1 + numpoles + i];
}
public:
/// Constrains that the first element in pvec is a linear combination
/// of the next numpoints elements in homogeneous coordinates with
/// weights given in the last numpoints elements.
/// Let `pvec = [q, p_1, p_2,... w_1, w_2,...]`, and
/// `givenfactors = [f_1, f_2,...]`, then this constraint ensures
/// `q*sum(w_i*f_i) = sum(p_i*w_i*f_i)`.
///
/// This constraint is currently used to ensure that a B-spline knot
/// point remains at the position determined by it's poles.
/// In that case, `q` is the x (or y) coordinate of the knot, `p_i` are
/// the x (or y) coordinates of the poles, and `w_i` are their weights.
/// Finally, `f_i` are obtained using `BSpline::getLinCombFactor()`.
ConstraintWeightedLinearCombination(size_t givennumpoints,
const std::vector<double*>& givenpvec,
const std::vector<double>& givenfactors);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
private:
std::vector<double> factors;
size_t numpoles;
};
// Slope at knot
class ConstraintSlopeAtBSplineKnot: public Constraint
{
private:
inline double* polexat(size_t i)
{
return pvec[i];
}
inline double* poleyat(size_t i)
{
return pvec[numpoles + i];
}
inline double* weightat(size_t i)
{
return pvec[2 * numpoles + i];
}
inline double* linep1x()
{
return pvec[3 * numpoles + 0];
}
inline double* linep1y()
{
return pvec[3 * numpoles + 1];
}
inline double* linep2x()
{
return pvec[3 * numpoles + 2];
}
inline double* linep2y()
{
return pvec[3 * numpoles + 3];
}
public:
// TODO: Should be able to make the geometries passed const
// Constrains the slope at a (C1 continuous) knot of the b-spline
ConstraintSlopeAtBSplineKnot(BSpline& b, Line& l, size_t knotindex);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
private:
std::vector<double> factors;
std::vector<double> slopefactors;
size_t numpoles;
};
// Point On BSpline
class ConstraintPointOnBSpline: public Constraint
{
private:
inline double* thepoint()
{
return pvec[0];
}
// TODO: better name because param has a different meaning here?
inline double* theparam()
{
return pvec[1];
}
inline double* poleat(size_t i)
{
return pvec[2 + (startpole + i) % bsp.poles.size()];
}
inline double* weightat(size_t i)
{
return pvec[2 + bsp.poles.size() + (startpole + i) % bsp.weights.size()];
}
void setStartPole(double u);
public:
/// TODO: Explain how it's provided
/// coordidx = 0 if x, 1 if y
ConstraintPointOnBSpline(double* point, double* initparam, int coordidx, BSpline& b);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
size_t numpoints;
BSpline& bsp;
size_t startpole;
};
// Difference
class ConstraintDifference: public Constraint
{
private:
inline double* param1()
{
return pvec[0];
}
inline double* param2()
{
return pvec[1];
}
inline double* difference()
{
return pvec[2];
}
public:
ConstraintDifference(double* p1, double* p2, double* d);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// P2PDistance
class ConstraintP2PDistance: public Constraint
{
private:
inline double* p1x()
{
return pvec[0];
}
inline double* p1y()
{
return pvec[1];
}
inline double* p2x()
{
return pvec[2];
}
inline double* p2y()
{
return pvec[3];
}
inline double* distance()
{
return pvec[4];
}
public:
ConstraintP2PDistance(Point& p1, Point& p2, double* d);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintP2PDistance()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
double maxStep(MAP_pD_D& dir, double lim = 1.) override;
};
// P2PAngle
class ConstraintP2PAngle: public Constraint
{
private:
inline double* p1x()
{
return pvec[0];
}
inline double* p1y()
{
return pvec[1];
}
inline double* p2x()
{
return pvec[2];
}
inline double* p2y()
{
return pvec[3];
}
inline double* angle()
{
return pvec[4];
}
double da;
public:
ConstraintP2PAngle(Point& p1, Point& p2, double* a, double da_ = 0.);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintP2PAngle()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
double maxStep(MAP_pD_D& dir, double lim = 1.) override;
};
// P2LDistance
class ConstraintP2LDistance: public Constraint
{
private:
inline double* p0x()
{
return pvec[0];
}
inline double* p0y()
{
return pvec[1];
}
inline double* p1x()
{
return pvec[2];
}
inline double* p1y()
{
return pvec[3];
}
inline double* p2x()
{
return pvec[4];
}
inline double* p2y()
{
return pvec[5];
}
inline double* distance()
{
return pvec[6];
}
public:
ConstraintP2LDistance(Point& p, Line& l, double* d);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintP2LDistance()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
double maxStep(MAP_pD_D& dir, double lim = 1.) override;
double abs(double darea);
};
// PointOnLine
class ConstraintPointOnLine: public Constraint
{
private:
inline double* p0x()
{
return pvec[0];
}
inline double* p0y()
{
return pvec[1];
}
inline double* p1x()
{
return pvec[2];
}
inline double* p1y()
{
return pvec[3];
}
inline double* p2x()
{
return pvec[4];
}
inline double* p2y()
{
return pvec[5];
}
public:
ConstraintPointOnLine(Point& p, Line& l);
ConstraintPointOnLine(Point& p, Point& lp1, Point& lp2);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPointOnLine()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// PointOnPerpBisector
class ConstraintPointOnPerpBisector: public Constraint
{
private:
inline double* p0x()
{
return pvec[0];
}
inline double* p0y()
{
return pvec[1];
}
inline double* p1x()
{
return pvec[2];
}
inline double* p1y()
{
return pvec[3];
}
inline double* p2x()
{
return pvec[4];
}
inline double* p2y()
{
return pvec[5];
}
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintPointOnPerpBisector(Point& p, Line& l);
ConstraintPointOnPerpBisector(Point& p, Point& lp1, Point& lp2);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPointOnPerpBisector() {};
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// Parallel
class ConstraintParallel: public Constraint
{
private:
inline double* l1p1x()
{
return pvec[0];
}
inline double* l1p1y()
{
return pvec[1];
}
inline double* l1p2x()
{
return pvec[2];
}
inline double* l1p2y()
{
return pvec[3];
}
inline double* l2p1x()
{
return pvec[4];
}
inline double* l2p1y()
{
return pvec[5];
}
inline double* l2p2x()
{
return pvec[6];
}
inline double* l2p2y()
{
return pvec[7];
}
public:
ConstraintParallel(Line& l1, Line& l2);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintParallel()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// Perpendicular
class ConstraintPerpendicular: public Constraint
{
private:
inline double* l1p1x()
{
return pvec[0];
}
inline double* l1p1y()
{
return pvec[1];
}
inline double* l1p2x()
{
return pvec[2];
}
inline double* l1p2y()
{
return pvec[3];
}
inline double* l2p1x()
{
return pvec[4];
}
inline double* l2p1y()
{
return pvec[5];
}
inline double* l2p2x()
{
return pvec[6];
}
inline double* l2p2y()
{
return pvec[7];
}
public:
ConstraintPerpendicular(Line& l1, Line& l2);
ConstraintPerpendicular(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPerpendicular()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// L2LAngle
class ConstraintL2LAngle: public Constraint
{
private:
inline double* l1p1x()
{
return pvec[0];
}
inline double* l1p1y()
{
return pvec[1];
}
inline double* l1p2x()
{
return pvec[2];
}
inline double* l1p2y()
{
return pvec[3];
}
inline double* l2p1x()
{
return pvec[4];
}
inline double* l2p1y()
{
return pvec[5];
}
inline double* l2p2x()
{
return pvec[6];
}
inline double* l2p2y()
{
return pvec[7];
}
inline double* angle()
{
return pvec[8];
}
public:
ConstraintL2LAngle(Line& l1, Line& l2, double* a);
ConstraintL2LAngle(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2, double* a);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintL2LAngle()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
double maxStep(MAP_pD_D& dir, double lim = 1.) override;
};
// MidpointOnLine
class ConstraintMidpointOnLine: public Constraint
{
private:
inline double* l1p1x()
{
return pvec[0];
}
inline double* l1p1y()
{
return pvec[1];
}
inline double* l1p2x()
{
return pvec[2];
}
inline double* l1p2y()
{
return pvec[3];
}
inline double* l2p1x()
{
return pvec[4];
}
inline double* l2p1y()
{
return pvec[5];
}
inline double* l2p2x()
{
return pvec[6];
}
inline double* l2p2y()
{
return pvec[7];
}
public:
ConstraintMidpointOnLine(Line& l1, Line& l2);
ConstraintMidpointOnLine(Point& l1p1, Point& l1p2, Point& l2p1, Point& l2p2);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintMidpointOnLine()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// TangentCircumf
class ConstraintTangentCircumf: public Constraint
{
private:
inline double* c1x()
{
return pvec[0];
}
inline double* c1y()
{
return pvec[1];
}
inline double* c2x()
{
return pvec[2];
}
inline double* c2y()
{
return pvec[3];
}
inline double* r1()
{
return pvec[4];
}
inline double* r2()
{
return pvec[5];
}
bool internal;
public:
ConstraintTangentCircumf(Point& p1,
Point& p2,
double* rd1,
double* rd2,
bool internal_ = false);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintTangentCircumf(bool internal_)
{
internal = internal_;
}
#endif
inline bool getInternal()
{
return internal;
};
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// PointOnEllipse
class ConstraintPointOnEllipse: public Constraint
{
private:
inline double* p1x()
{
return pvec[0];
}
inline double* p1y()
{
return pvec[1];
}
inline double* cx()
{
return pvec[2];
}
inline double* cy()
{
return pvec[3];
}
inline double* f1x()
{
return pvec[4];
}
inline double* f1y()
{
return pvec[5];
}
inline double* rmin()
{
return pvec[6];
}
public:
ConstraintPointOnEllipse(Point& p, Ellipse& e);
ConstraintPointOnEllipse(Point& p, ArcOfEllipse& a);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPointOnEllipse()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintEllipseTangentLine: public Constraint
{
private:
Line l;
Ellipse e;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintEllipseTangentLine(Line& l, Ellipse& e);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintInternalAlignmentPoint2Ellipse: public Constraint
{
public:
ConstraintInternalAlignmentPoint2Ellipse(Ellipse& e,
Point& p1,
InternalAlignmentType alignmentType);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
private:
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
Ellipse e;
Point p;
InternalAlignmentType AlignmentType;
};
class ConstraintInternalAlignmentPoint2Hyperbola: public Constraint
{
public:
ConstraintInternalAlignmentPoint2Hyperbola(Hyperbola& e,
Point& p1,
InternalAlignmentType alignmentType);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
private:
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
Hyperbola e;
Point p;
InternalAlignmentType AlignmentType;
};
class ConstraintEqualMajorAxesConic: public Constraint
{
private:
MajorRadiusConic* e1;
MajorRadiusConic* e2;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintEqualMajorAxesConic(MajorRadiusConic* a1, MajorRadiusConic* a2);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintEqualFocalDistance: public Constraint
{
private:
ArcOfParabola* e1;
ArcOfParabola* e2;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintEqualFocalDistance(ArcOfParabola* a1, ArcOfParabola* a2);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintCurveValue: public Constraint
{
private:
// defines, which coordinate of point is being constrained by this constraint
inline double* pcoord()
{
return pvec[2];
}
inline double* u()
{
return pvec[3];
}
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
Curve* crv;
Point p;
public:
/**
* @brief ConstraintCurveValue: solver constraint that ties parameter value with point
* coordinates, according to curve's parametric equation.
* @param p : endpoint to be constrained
* @param pcoord : pointer to point coordinate to be constrained. Must be either p.x or p.y
* @param crv : the curve (crv->Value() must be functional)
* @param u : pointer to u parameter corresponding to the point
*/
ConstraintCurveValue(Point& p, double* pcoord, Curve& crv, double* u);
~ConstraintCurveValue() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
double maxStep(MAP_pD_D& dir, double lim = 1.) override;
};
// PointOnHyperbola
class ConstraintPointOnHyperbola: public Constraint
{
private:
inline double* p1x()
{
return pvec[0];
}
inline double* p1y()
{
return pvec[1];
}
inline double* cx()
{
return pvec[2];
}
inline double* cy()
{
return pvec[3];
}
inline double* f1x()
{
return pvec[4];
}
inline double* f1y()
{
return pvec[5];
}
inline double* rmin()
{
return pvec[6];
}
public:
ConstraintPointOnHyperbola(Point& p, Hyperbola& e);
ConstraintPointOnHyperbola(Point& p, ArcOfHyperbola& a);
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPointOnHyperbola()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// PointOnParabola
class ConstraintPointOnParabola: public Constraint
{
private:
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
Parabola* parab;
Point p;
public:
ConstraintPointOnParabola(Point& p, Parabola& e);
ConstraintPointOnParabola(Point& p, ArcOfParabola& a);
~ConstraintPointOnParabola() override;
#ifdef _GCS_EXTRACT_SOLVER_SUBSYSTEM_
inline ConstraintPointOnParabola()
{}
#endif
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintAngleViaPoint: public Constraint
{
private:
inline double* angle()
{
return pvec[0];
};
Curve* crv1;
Curve* crv2;
// These two pointers hold copies of the curves that were passed on
// constraint creation. The curves must be deleted upon destruction of
// the constraint. It is necessary to have copies, since messing with
// original objects that were passed is a very bad idea (but messing is
// necessary, because we need to support redirectParams()/revertParams
// functions.
// The pointers in the curves need to be reconstructed if pvec was redirected
// (test pvecChangedFlag variable before use!)
// poa=point of angle //needs to be reconstructed if pvec was redirected/reverted. The point is
// easily shallow-copied by C++, so no pointer type here and no delete is necessary.
Point poa;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
public:
ConstraintAngleViaPoint(Curve& acrv1, Curve& acrv2, Point p, double* angle);
~ConstraintAngleViaPoint() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintAngleViaTwoPoints: public Constraint
{
private:
inline double* angle()
{
return pvec[0];
};
Curve* crv1;
Curve* crv2;
// These two pointers hold copies of the curves that were passed on
// constraint creation. The curves must be deleted upon destruction of
// the constraint. It is necessary to have copies, since messing with
// original objects that were passed is a very bad idea (but messing is
// necessary, because we need to support redirectParams()/revertParams
// functions.
// The pointers in the curves need to be reconstructed if pvec was redirected
// (test pvecChangedFlag variable before use!)
// poa=point of angle //needs to be reconstructed if pvec was redirected/reverted. The points
// are easily shallow-copied by C++, so no pointer type here and no delete is necessary. We use
// two points in this method as a workaround for B-splines (and friends). There, normals at
// general points are not implemented, just at their stored start/end points.
Point poa1;
Point poa2;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
public:
ConstraintAngleViaTwoPoints(Curve& acrv1, Curve& acrv2, Point p1, Point p2, double* angle);
~ConstraintAngleViaTwoPoints() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// snell's law angles constrainer. Point needs to lie on all three curves to be constraied.
class ConstraintSnell: public Constraint
{
private:
inline double* n1()
{
return pvec[0];
};
inline double* n2()
{
return pvec[1];
};
Curve* ray1;
Curve* ray2;
Curve* boundary;
// These pointers hold copies of the curves that were passed on
// constraint creation. The curves must be deleted upon destruction of
// the constraint. It is necessary to have copies, since messing with
// original objects that were passed is a very bad idea (but messing is
// necessary, because we need to support redirectParams()/revertParams
// functions.
// The pointers in the curves need to be reconstructed if pvec was redirected
// (test pvecChangedFlag variable before use!)
// poa=point of refraction //needs to be reconstructed if pvec was redirected/reverted. The
// point is easily shallow-copied by C++, so no pointer type here and no delete is necessary.
Point poa;
bool flipn1, flipn2;
// writes pointers in pvec to the parameters of crv1, crv2 and poa
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
// n1dn2 = n1 divided by n2. from n1 to n2. flipn1 = true instructs to flip ray1's tangent
ConstraintSnell(Curve& ray1,
Curve& ray2,
Curve& boundary,
Point p,
double* n1,
double* n2,
bool flipn1,
bool flipn2);
~ConstraintSnell() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintAngleViaPointAndParam: public Constraint
{
private:
inline double* angle()
{
return pvec[0];
};
inline double* cparam()
{
return pvec[3];
};
Curve* crv1;
Curve* crv2;
// These two pointers hold copies of the curves that were passed on
// constraint creation. The curves must be deleted upon destruction of
// the constraint. It is necessary to have copies, since messing with
// original objects that were passed is a very bad idea (but messing is
// necessary, because we need to support redirectParams()/revertParams
// functions.
// The pointers in the curves need to be reconstructed if pvec was redirected
// (test pvecChangedFlag variable before use!)
Point poa; // poa=point of angle //needs to be reconstructed if pvec was redirected/reverted.
// The point is easily shallow-copied by C++, so no pointer type here and no delete
// is necessary.
void
ReconstructGeomPointers(); // writes pointers in pvec to the parameters of crv1, crv2 and poa
public:
// We assume first curve needs param1
ConstraintAngleViaPointAndParam(Curve& acrv1,
Curve& acrv2,
Point p,
double* param1,
double* angle);
~ConstraintAngleViaPointAndParam() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// TODO: Do we need point here at all?
class ConstraintAngleViaPointAndTwoParams: public Constraint
{
private:
inline double* angle()
{
return pvec[0];
};
inline double* cparam1()
{
return pvec[3];
};
inline double* cparam2()
{
return pvec[4];
};
Curve* crv1;
Curve* crv2;
// These two pointers hold copies of the curves that were passed on
// constraint creation. The curves must be deleted upon destruction of
// the constraint. It is necessary to have copies, since messing with
// original objects that were passed is a very bad idea (but messing is
// necessary, because we need to support redirectParams()/revertParams
// functions.
// The pointers in the curves need to be reconstructed if pvec was redirected
// (test pvecChangedFlag variable before use!)
Point poa; // poa=point of angle //needs to be reconstructed if pvec was redirected/reverted.
// The point is easily shallow-copied by C++, so no pointer type here and no delete
// is necessary.
void
ReconstructGeomPointers(); // writes pointers in pvec to the parameters of crv1, crv2 and poa
public:
ConstraintAngleViaPointAndTwoParams(Curve& acrv1,
Curve& acrv2,
Point p,
double* param1,
double* param2,
double* angle);
~ConstraintAngleViaPointAndTwoParams() override;
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintEqualLineLength: public Constraint
{
private:
Line l1;
Line l2;
// writes pointers in pvec to the parameters of line1, line2
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintEqualLineLength(Line& l1, Line& l2);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
class ConstraintC2CDistance: public Constraint
{
private:
Circle c1;
Circle c2;
double* d;
inline double* distance()
{
return pvec[0];
}
// writes pointers in pvec to the parameters of c1, c2
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintC2CDistance(Circle& c1, Circle& c2, double* d);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// C2LDistance
class ConstraintC2LDistance: public Constraint
{
private:
Circle circle;
Line line;
double* d;
inline double* distance()
{
return pvec[0];
}
// writes pointers in pvec to the parameters of c, l
void ReconstructGeomPointers();
// error and gradient combined. Values are returned through pointers.
void errorgrad(double* err, double* grad, double* param);
public:
ConstraintC2LDistance(Circle& c, Line& l, double* d);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// P2CDistance
class ConstraintP2CDistance: public Constraint
{
private:
Circle circle;
Point pt;
double* d;
inline double* distance()
{
return pvec[0];
}
void ReconstructGeomPointers(); // writes pointers in pvec to the parameters of c
void
errorgrad(double* err,
double* grad,
double* param); // error and gradient combined. Values are returned through pointers.
public:
ConstraintP2CDistance(Point& p, Circle& c, double* d);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
// ArcLength
class ConstraintArcLength: public Constraint
{
private:
Arc arc;
double* d;
inline double* distance()
{
return pvec[0];
}
void ReconstructGeomPointers(); // writes pointers in pvec to the parameters of a
void
errorgrad(double* err,
double* grad,
double* param); // error and gradient combined. Values are returned through pointers.
public:
ConstraintArcLength(Arc& a, double* d);
ConstraintType getTypeId() override;
void rescale(double coef = 1.) override;
double error() override;
double grad(double*) override;
};
} // namespace GCS
#endif // PLANEGCS_CONSTRAINTS_H