#include <SketchSolver_Storage.h>
+#include <math.h>
+
/** \brief Search the entity/parameter with specified ID in the list of elements
* \param[in] theEntityID unique ID of the element
* \param[in] theEntities list of elements
: myParamMaxID(SLVS_E_UNKNOWN),
myEntityMaxID(SLVS_E_UNKNOWN),
myConstrMaxID(SLVS_C_UNKNOWN),
- myNeedToResolve(false)
+ myFixed(SLVS_E_UNKNOWN),
+ myNeedToResolve(false),
+ myDuplicatedConstraint(false)
{
}
}
// Remove parameter
myParameters.erase(myParameters.begin() + aPos);
+ myParamMaxID = myParameters.empty() ? SLVS_E_UNKNOWN : myParameters.back().h;
myNeedToResolve = true;
myRemovedParameters.insert(theParamID);
return true;
bool aResult = true;
int aPos = Search(theEntityID, myEntities);
if (aPos >= 0 && aPos < (int)myEntities.size()) {
- // Firstly, check the entity is not used elsewhere
+ // Firstly, check the entity and its attributes is not used elsewhere
+ std::set<Slvs_hEntity> anEntAndSubs;
+ anEntAndSubs.insert(theEntityID);
+ for (int i = 0; i < 4; i++)
+ if (myEntities[aPos].point[i] != SLVS_E_UNKNOWN)
+ anEntAndSubs.insert(myEntities[aPos].point[i]);
+
std::vector<Slvs_Entity>::const_iterator anEntIter = myEntities.begin();
for (; anEntIter != myEntities.end(); anEntIter++) {
for (int i = 0; i < 4; i++)
- if (anEntIter->point[i] == theEntityID)
+ if (anEntAndSubs.find(anEntIter->point[i]) != anEntAndSubs.end())
return false;
- if (anEntIter->distance == theEntityID)
+ if (anEntAndSubs.find(anEntIter->distance) != anEntAndSubs.end())
return false;
}
std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
aConstrIter->entityA, aConstrIter->entityB,
aConstrIter->entityC, aConstrIter->entityD};
for (int i = 0; i < 6; i++)
- if (anEntIDs[i] == theEntityID)
+ if (anEntAndSubs.find(anEntIDs[i]) != anEntAndSubs.end())
return false;
}
// The entity is not used, remove it and its parameters
Slvs_Entity anEntity = myEntities[aPos];
myEntities.erase(myEntities.begin() + aPos);
+ myEntityMaxID = myEntities.empty() ? SLVS_E_UNKNOWN : myEntities.back().h;
if (anEntity.distance != SLVS_E_UNKNOWN)
aResult = aResult && removeParameter(anEntity.distance);
for (int i = 0; i < 4; i++)
aResult = removeEntity(anEntity.point[i]) && aResult;
myNeedToResolve = true;
myRemovedEntities.insert(theEntityID);
+ if (anEntity.type == SLVS_E_POINT_IN_2D || anEntity.type == SLVS_E_POINT_IN_3D)
+ removeCoincidentPoint(theEntityID);
}
return aResult;
}
// Entity is not found, return empty object
static Slvs_Entity aDummy;
- aDummy.h = 0;
+ aDummy.h = SLVS_E_UNKNOWN;
return aDummy;
}
+Slvs_hEntity SketchSolver_Storage::copyEntity(const Slvs_hEntity& theCopied)
+{
+ int aPos = Search(theCopied, myEntities);
+ if (aPos < 0 || aPos >= (int)myEntities.size())
+ return SLVS_E_UNKNOWN;
+
+ Slvs_Entity aCopy = myEntities[aPos];
+ aCopy.h = SLVS_E_UNKNOWN;
+ int i = 0;
+ while (aCopy.point[i] != SLVS_E_UNKNOWN) {
+ aCopy.point[i] = copyEntity(aCopy.point[i]);
+ i++;
+ }
+ if (aCopy.param[0] != SLVS_E_UNKNOWN) {
+ aPos = Search(aCopy.param[0], myParameters);
+ i = 0;
+ while (aCopy.param[i] != SLVS_E_UNKNOWN) {
+ Slvs_Param aNewParam = myParameters[aPos];
+ aNewParam.h = SLVS_E_UNKNOWN;
+ aCopy.param[i] = addParameter(aNewParam);
+ i++;
+ aPos++;
+ }
+ }
+ return addEntity(aCopy);
+}
+
+void SketchSolver_Storage::copyEntity(const Slvs_hEntity& theFrom, const Slvs_hEntity& theTo)
+{
+ int aPosFrom = Search(theFrom, myEntities);
+ int aPosTo = Search(theTo, myEntities);
+ if (aPosFrom < 0 || aPosFrom >= (int)myEntities.size() ||
+ aPosTo < 0 || aPosTo >= (int)myEntities.size())
+ return;
+
+ Slvs_Entity aEntFrom = myEntities[aPosFrom];
+ Slvs_Entity aEntTo = myEntities[aPosTo];
+ int i = 0;
+ while (aEntFrom.point[i] != SLVS_E_UNKNOWN) {
+ copyEntity(aEntFrom.point[i], aEntTo.point[i]);
+ i++;
+ }
+ if (aEntFrom.param[0] != SLVS_E_UNKNOWN) {
+ aPosFrom = Search(aEntFrom.param[0], myParameters);
+ aPosTo = Search(aEntTo.param[0], myParameters);
+ i = 0;
+ while (aEntFrom.param[i] != SLVS_E_UNKNOWN) {
+ myParameters[aPosTo++].val = myParameters[aPosFrom++].val;
+ i++;
+ }
+ }
+}
+
+
+bool SketchSolver_Storage::isPointFixed(
+ const Slvs_hEntity& thePointID, Slvs_hConstraint& theFixed, bool theAccurate) const
+{
+ // Search the set of coincident points
+ std::set<Slvs_hEntity> aCoincident;
+ aCoincident.insert(thePointID);
+ std::vector< std::set<Slvs_hEntity> >::const_iterator aCPIter = myCoincidentPoints.begin();
+ for (; aCPIter != myCoincidentPoints.end(); aCPIter++)
+ if (aCPIter->find(thePointID) != aCPIter->end()) {
+ aCoincident = *aCPIter;
+ break;
+ }
+
+ // Search the Rigid constraint
+ std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
+ for (; aConstrIter != myConstraints.end(); aConstrIter++)
+ if (aConstrIter->type == SLVS_C_WHERE_DRAGGED &&
+ aCoincident.find(aConstrIter->ptA) != aCoincident.end()) {
+ theFixed = aConstrIter->h;
+ return true;
+ }
+
+ if (theAccurate) {
+ // Try to find the fixed entity which uses such point or its coincidence
+ std::vector<Slvs_Entity>::const_iterator anEntIter = myEntities.begin();
+ for (; anEntIter != myEntities.end(); anEntIter++) {
+ for (int i = 0; i < 4; i++) {
+ Slvs_hEntity aPt = anEntIter->point[i];
+ if (aPt != SLVS_E_UNKNOWN &&
+ (aPt == thePointID || aCoincident.find(aPt) != aCoincident.end())) {
+ if (isEntityFixed(anEntIter->h, true))
+ return true;
+ }
+ }
+ }
+ }
+ return SLVS_E_UNKNOWN;
+}
+
+bool SketchSolver_Storage::isEntityFixed(const Slvs_hEntity& theEntityID, bool theAccurate) const
+{
+ int aPos = Search(theEntityID, myEntities);
+ if (aPos < 0 || aPos >= (int)myEntities.size())
+ return false;
+
+ // Firstly, find how many points are under Rigid constraint
+ int aNbFixed = 0;
+ for (int i = 0; i < 4; i++) {
+ Slvs_hEntity aPoint = myEntities[aPos].point[i];
+ if (aPoint == SLVS_E_UNKNOWN)
+ continue;
+
+ std::set<Slvs_hEntity> aCoincident;
+ aCoincident.insert(aPoint);
+ std::vector< std::set<Slvs_hEntity> >::const_iterator aCPIter = myCoincidentPoints.begin();
+ for (; aCPIter != myCoincidentPoints.end(); aCPIter++)
+ if (aCPIter->find(aPoint) != aCPIter->end()) {
+ aCoincident = *aCPIter;
+ break;
+ }
+
+ // Search the Rigid constraint
+ std::vector<Slvs_Constraint>::const_iterator aConstrIter = myConstraints.begin();
+ for (; aConstrIter != myConstraints.end(); aConstrIter++)
+ if (aConstrIter->type == SLVS_C_WHERE_DRAGGED &&
+ aCoincident.find(aConstrIter->ptA) != aCoincident.end())
+ aNbFixed++;
+ }
+
+ std::list<Slvs_Constraint> aList;
+ std::list<Slvs_Constraint>::iterator anIt;
+ Slvs_hConstraint aTempID; // used in isPointFixed() method
+
+ if (myEntities[aPos].type == SLVS_E_LINE_SEGMENT) {
+ if (aNbFixed == 2)
+ return true;
+ else if (aNbFixed == 0 || !theAccurate)
+ return false;
+ // Additional check (the line may be fixed if it is used by different constraints):
+ // 1. The line is used in Equal constraint, another entity is fixed and there is a fixed point on line
+ aList = getConstraintsByType(SLVS_C_PT_ON_LINE);
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID && isPointFixed(anIt->ptA, aTempID))
+ break;
+ if (anIt != aList.end()) {
+ aList = getConstraintsByType(SLVS_C_EQUAL_LENGTH_LINES);
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_EQUAL_LINE_ARC_LEN));
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID || anIt->entityB == theEntityID) {
+ Slvs_hEntity anOther = anIt->entityA == theEntityID ? anIt->entityB : anIt->entityA;
+ if (isEntityFixed(anOther, false))
+ return true;
+ }
+ }
+ // 2. The line is used in Parallel/Perpendicular/Vertical/Horizontal and Length constraints
+ aList = getConstraintsByType(SLVS_C_PARALLEL);
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_PERPENDICULAR));
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_VERTICAL));
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_HORIZONTAL));
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID || anIt->entityB == theEntityID) {
+ Slvs_hEntity anOther = anIt->entityA == theEntityID ? anIt->entityB : anIt->entityA;
+ if (isEntityFixed(anOther, false))
+ break;
+ }
+ if (anIt != aList.end()) {
+ aList = getConstraintsByType(SLVS_C_PT_PT_DISTANCE);
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if ((anIt->ptA == myEntities[aPos].point[0] && anIt->ptB == myEntities[aPos].point[1]) ||
+ (anIt->ptA == myEntities[aPos].point[1] && anIt->ptB == myEntities[aPos].point[0]))
+ return true;
+ }
+ // 3. Another verifiers ...
+ } else if (myEntities[aPos].type == SLVS_E_CIRCLE) {
+ if (aNbFixed == 0)
+ return false;
+ // Search for Diameter constraint
+ aList = getConstraintsByType(SLVS_C_DIAMETER);
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID)
+ return true;
+ if (!theAccurate)
+ return false;
+ // Additional check (the circle may be fixed if it is used by different constraints):
+ // 1. The circle is used in Equal constraint and another entity is fixed
+ aList = getConstraintsByType(SLVS_C_EQUAL_RADIUS);
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID || anIt->entityB == theEntityID) {
+ Slvs_hEntity anOther = anIt->entityA == theEntityID ? anIt->entityB : anIt->entityA;
+ if (isEntityFixed(anOther, false))
+ return true;
+ }
+ // 2. Another verifiers ...
+ } else if (myEntities[aPos].type == SLVS_E_ARC_OF_CIRCLE) {
+ if (aNbFixed > 2)
+ return true;
+ else if (aNbFixed <= 1)
+ return false;
+ // Search for Diameter constraint
+ aList = getConstraintsByType(SLVS_C_DIAMETER);
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID)
+ return true;
+ if (!theAccurate)
+ return false;
+ // Additional check (the arc may be fixed if it is used by different constraints):
+ // 1. The arc is used in Equal constraint and another entity is fixed
+ aList = getConstraintsByType(SLVS_C_EQUAL_RADIUS);
+ aList.splice(aList.end(), getConstraintsByType(SLVS_C_EQUAL_LINE_ARC_LEN));
+ for (anIt = aList.begin(); anIt != aList.end(); anIt++)
+ if (anIt->entityA == theEntityID || anIt->entityB == theEntityID) {
+ Slvs_hEntity anOther = anIt->entityA == theEntityID ? anIt->entityB : anIt->entityA;
+ if (isEntityFixed(anOther, false))
+ return true;
+ }
+ // 2. Another verifiers ...
+ }
+ return false;
+}
+
Slvs_hConstraint SketchSolver_Storage::addConstraint(const Slvs_Constraint& theConstraint)
{
}
Slvs_Constraint aConstraint = theConstraint;
+
+ // Find a constraint with same type uses same arguments to show user overconstraint situation
+ std::vector<Slvs_Constraint>::iterator aCIt = myConstraints.begin();
+ for (; aCIt != myConstraints.end(); aCIt++) {
+ if (aConstraint.type != aCIt->type)
+ continue;
+ if (aConstraint.ptA == aCIt->ptA && aConstraint.ptB == aCIt->ptB &&
+ aConstraint.entityA == aCIt->entityA && aConstraint.entityB == aCIt->entityB &&
+ aConstraint.entityC == aCIt->entityC && aConstraint.entityD == aCIt->entityD)
+ myDuplicatedConstraint = true;
+ }
+
if (aConstraint.h > myConstrMaxID)
myConstrMaxID = aConstraint.h;
else
aConstraint.h = ++myConstrMaxID;
myConstraints.push_back(aConstraint);
myNeedToResolve = true;
+ if (aConstraint.type == SLVS_C_POINTS_COINCIDENT)
+ addCoincidentPoints(aConstraint.ptA, aConstraint.ptB);
return aConstraint.h;
}
if (aPos >= 0 && aPos < (int)myConstraints.size()) {
myNeedToResolve = myNeedToResolve || IsNotEqual(myConstraints[aPos], theConstraint);
myConstraints[aPos] = theConstraint;
+ if (theConstraint.type == SLVS_C_POINTS_COINCIDENT)
+ addCoincidentPoints(theConstraint.ptA, theConstraint.ptB);
return theConstraint.h;
}
}
if (aPos >= 0 && aPos < (int)myConstraints.size()) {
Slvs_Constraint aConstraint = myConstraints[aPos];
myConstraints.erase(myConstraints.begin() + aPos);
+ myConstrMaxID = myConstraints.empty() ? SLVS_E_UNKNOWN : myConstraints.back().h;
myNeedToResolve = true;
myRemovedConstraints.insert(theConstraintID);
// Remove all entities
aConstraint.entityA, aConstraint.entityB,
aConstraint.entityC, aConstraint.entityD};
for (int i = 0; i < 6; i++)
- if (anEntities[i] != SLVS_E_UNKNOWN) {
+ if (anEntities[i] != SLVS_E_UNKNOWN)
aResult = removeEntity(anEntities[i]) && aResult;
- // remove temporary fixed points, if exists
- std::vector<Slvs_hEntity>::iterator aFPIt = myFixedPoints.begin();
- for (; aFPIt != myFixedPoints.end(); aFPIt++)
- if (*aFPIt == anEntities[i]) {
- myFixedPoints.erase(aFPIt);
- break;
- }
- }
+ // remove temporary fixed point, if available
+ if (myFixed == theConstraintID)
+ myFixed = SLVS_E_UNKNOWN;
+ if (myDuplicatedConstraint) {
+ // Check the duplicated constraints are still available
+ myDuplicatedConstraint = false;
+ std::vector<Slvs_Constraint>::const_iterator anIt1 = myConstraints.begin();
+ std::vector<Slvs_Constraint>::const_iterator anIt2 = myConstraints.begin();
+ for (; anIt1 != myConstraints.end() && !myDuplicatedConstraint; anIt1++)
+ for (anIt2 = anIt1+1; anIt2 != myConstraints.end() && !myDuplicatedConstraint; anIt2++) {
+ if (anIt1->type != anIt2->type)
+ continue;
+ if (anIt1->ptA == anIt2->ptA && anIt1->ptB == anIt2->ptB &&
+ anIt1->entityA == anIt2->entityA && anIt1->entityB == anIt2->entityB &&
+ anIt1->entityC == anIt2->entityC && anIt1->entityD == anIt2->entityD)
+ myDuplicatedConstraint = true;
+ }
+ }
}
return aResult;
}
return aDummy;
}
-void SketchSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
+std::list<Slvs_Constraint> SketchSolver_Storage::getConstraintsByType(int theConstraintType) const
{
+ std::list<Slvs_Constraint> aResult;
+ std::vector<Slvs_Constraint>::const_iterator aCIter = myConstraints.begin();
+ for (; aCIter != myConstraints.end(); aCIter++)
+ if (aCIter->type == theConstraintType)
+ aResult.push_back(*aCIter);
+ return aResult;
+}
+
+
+void SketchSolver_Storage::addConstraintWhereDragged(const Slvs_hConstraint& theConstraintID)
+{
+ if (myFixed != SLVS_E_UNKNOWN)
+ return; // the point is already fixed
int aPos = Search(theConstraintID, myConstraints);
- myFixedPoints.push_back(myConstraints[aPos].ptA);
+ if (aPos >= 0 && aPos < (int)myConstraints.size())
+ myFixed = theConstraintID;
+}
+
+void SketchSolver_Storage::addTemporaryConstraint(const Slvs_hConstraint& theConstraintID)
+{
+ myTemporaryConstraints.insert(theConstraintID);
+}
+
+void SketchSolver_Storage::removeTemporaryConstraints()
+{
+ myTemporaryConstraints.clear();
+}
+
+int SketchSolver_Storage::deleteTemporaryConstraint()
+{
+ if (myTemporaryConstraints.empty())
+ return 0;
+ // Search the point-on-line or a non-rigid constraint
+ std::set<Slvs_hConstraint>::iterator aCIt = myTemporaryConstraints.begin();
+ for (; aCIt != myTemporaryConstraints.end(); aCIt++) {
+ int aPos = Search(*aCIt, myConstraints);
+ if (aPos >= (int)myConstraints.size() || myConstraints[aPos].type != SLVS_C_WHERE_DRAGGED)
+ break;
+ std::vector<Slvs_Constraint>::iterator anIt = myConstraints.begin();
+ for (; anIt != myConstraints.end(); anIt++)
+ if (anIt->type == SLVS_C_PT_ON_LINE && anIt->ptA == myConstraints[aPos].ptA)
+ break;
+ if (anIt != myConstraints.end())
+ break;
+ }
+ if (aCIt == myTemporaryConstraints.end())
+ aCIt = myTemporaryConstraints.begin();
+ bool aNewFixed = (*aCIt == myFixed);
+ removeConstraint(*aCIt);
+ myTemporaryConstraints.erase(aCIt);
+ if (aNewFixed) {
+ for (aCIt = myTemporaryConstraints.begin(); aCIt != myTemporaryConstraints.end(); aCIt++) {
+ int aPos = Search(*aCIt, myConstraints);
+ if (myConstraints[aPos].type == SLVS_C_WHERE_DRAGGED) {
+ myFixed = *aCIt;
+ break;
+ }
+ }
+ }
+ return (int)myTemporaryConstraints.size();
}
+bool SketchSolver_Storage::isTemporary(const Slvs_hConstraint& theConstraintID) const
+{
+ return myTemporaryConstraints.find(theConstraintID) != myTemporaryConstraints.end();
+}
+
+
void SketchSolver_Storage::getRemoved(
std::set<Slvs_hParam>& theParameters,
std::set<Slvs_hEntity>& theEntities,
{
theSolver.setParameters(myParameters.data(), (int)myParameters.size());
theSolver.setEntities(myEntities.data(), (int)myEntities.size());
- theSolver.setConstraints(myConstraints.data(), (int)myConstraints.size());
- // initialize fixed points
- if (!myFixedPoints.empty()) {
- int aPos = Search(myFixedPoints.front(), myEntities);
+ // Copy constraints excluding the fixed one
+ std::vector<Slvs_Constraint> aConstraints = myConstraints;
+ if (myFixed != SLVS_E_UNKNOWN) {
+ Slvs_hEntity aFixedPoint = SLVS_E_UNKNOWN;
+ std::vector<Slvs_Constraint>::iterator anIt = aConstraints.begin();
+ for (; anIt != aConstraints.end(); anIt++)
+ if (anIt->h == myFixed) {
+ aFixedPoint = anIt->ptA;
+ aConstraints.erase(anIt);
+ break;
+ }
+ // set dragged parameters
+ int aPos = Search(aFixedPoint, myEntities);
theSolver.setDraggedParameters(myEntities[aPos].param);
}
+ theSolver.setConstraints(aConstraints.data(), (int)aConstraints.size());
+}
+
+void SketchSolver_Storage::addCoincidentPoints(
+ const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2)
+{
+ std::vector< std::set<Slvs_hEntity> >::iterator aCIter = myCoincidentPoints.begin();
+ std::vector< std::set<Slvs_hEntity> >::iterator aFoundIter = myCoincidentPoints.end(); // already found coincidence
+ bool isFound = false;
+ for (; aCIter != myCoincidentPoints.end(); aCIter++) {
+ bool isFirstFound = aCIter->find(thePoint1) != aCIter->end();
+ bool isSecondFound = aCIter->find(thePoint2) != aCIter->end();
+ isFound = isFound || isFirstFound || isSecondFound;
+ if (isFirstFound && isSecondFound)
+ break; // already coincident
+ else if (isFirstFound || isSecondFound) {
+ if (aFoundIter != myCoincidentPoints.end()) {
+ // merge two sets
+ aFoundIter->insert(aCIter->begin(), aCIter->end());
+ myCoincidentPoints.erase(aCIter);
+ break;
+ }
+ aCIter->insert(thePoint1);
+ aCIter->insert(thePoint2);
+ }
+ }
+ // coincident points not found
+ if (!isFound) {
+ std::set<Slvs_hEntity> aNewSet;
+ aNewSet.insert(thePoint1);
+ aNewSet.insert(thePoint2);
+ myCoincidentPoints.push_back(aNewSet);
+ }
+}
+
+void SketchSolver_Storage::removeCoincidentPoint(const Slvs_hEntity& thePoint)
+{
+ std::vector< std::set<Slvs_hEntity> >::iterator aCIter = myCoincidentPoints.begin();
+ for (; aCIter != myCoincidentPoints.end(); aCIter++)
+ if (aCIter->find(thePoint) != aCIter->end()) {
+ aCIter->erase(thePoint);
+ if (aCIter->size() <= 1)
+ myCoincidentPoints.erase(aCIter);
+ break;
+ }
+}
+
+bool SketchSolver_Storage::isCoincident(
+ const Slvs_hEntity& thePoint1, const Slvs_hEntity& thePoint2) const
+{
+ std::vector< std::set<Slvs_hEntity> >::const_iterator aCIter = myCoincidentPoints.begin();
+ for (; aCIter != myCoincidentPoints.end(); aCIter++)
+ if (aCIter->find(thePoint1) != aCIter->end() && aCIter->find(thePoint2) != aCIter->end())
+ return true;
+ // precise checking of coincidence
+ int aEnt1Pos = Search(thePoint1, myEntities);
+ int aEnt2Pos = Search(thePoint2, myEntities);
+ if (aEnt1Pos >= 0 && aEnt1Pos < (int)myEntities.size() &&
+ aEnt2Pos >= 0 && aEnt2Pos < (int)myEntities.size()) {
+ double aDist[2];
+ int aParamPos;
+ for (int i = 0; i < 2; i++) {
+ aParamPos = Search(myEntities[aEnt1Pos].param[i], myParameters);
+ aDist[i] = myParameters[aParamPos].val;
+ aParamPos = Search(myEntities[aEnt2Pos].param[i], myParameters);
+ aDist[i] -= myParameters[aParamPos].val;
+ }
+ if (aDist[0] * aDist[0] + aDist[1] * aDist[1] < tolerance * tolerance)
+ return true;
+ }
+ return false;
}
+
+
// ========================================================
// ========= Auxiliary functions ===============
// ========================================================
{
int aResIndex = theEntityID <= theEntities.size() ? theEntityID - 1 : 0;
int aVecSize = theEntities.size();
+ if (theEntities.empty())
+ return 1;
while (aResIndex >= 0 && theEntities[aResIndex].h > theEntityID)
aResIndex--;
while (aResIndex < aVecSize && aResIndex >= 0 && theEntities[aResIndex].h < theEntityID)
aResIndex++;
- if (aResIndex == -1)
+ if (aResIndex == -1 || (aResIndex < aVecSize && theEntities[aResIndex].h != theEntityID))
aResIndex = aVecSize;
return aResIndex;
}