+
+bool PlaneGCSSolver_UpdateCoincidence::isPointOnEntity(
+ const EntityWrapperPtr& thePoint,
+ const EntityWrapperPtr& theEntity)
+{
+ std::list<CoincidentEntities>::iterator anIt = findGroupOfCoincidence(thePoint);
+ if (anIt == myCoincident.end())
+ return false;
+
+ if (anIt->isExist(theEntity))
+ return true;
+
+ if (theEntity->type() == ENTITY_LINE) {
+ std::shared_ptr<GCS::Line> aLine = std::dynamic_pointer_cast<GCS::Line>(
+ std::dynamic_pointer_cast<PlaneGCSSolver_EdgeWrapper>(theEntity)->entity());
+ return anIt->isExist(aLine->p1) || anIt->isExist(aLine->p2);
+ }
+ return false;
+}
+
+std::list<PlaneGCSSolver_UpdateCoincidence::CoincidentEntities>::iterator
+ PlaneGCSSolver_UpdateCoincidence::findGroupOfCoincidence(const EntityWrapperPtr& theEntity)
+{
+ if (theEntity->type() != ENTITY_POINT)
+ return myCoincident.end();
+
+ std::list<CoincidentEntities>::iterator aFound = myCoincident.begin();
+ for (; aFound != myCoincident.end(); ++aFound)
+ if (aFound->isExist(theEntity))
+ break;
+ return aFound;
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::addToGroupOfCoincidence(
+ CoincidentEntities& theGroup, const EntityWrapperPtr& theEntity)
+{
+ if (theGroup.isExist(theEntity))
+ return false;
+ return theGroup.add(theEntity);
+}
+
+
+
+
+
+static const GCS::Point& toPoint(const EntityWrapperPtr& theEntity)
+{
+ PointWrapperPtr aPoint = std::dynamic_pointer_cast<PlaneGCSSolver_PointWrapper>(theEntity);
+ return *(aPoint->point());
+}
+
+static double squareDistance(const GCS::Point& thePoint1, const GCS::Point& thePoint2)
+{
+ double dx = *thePoint1.x - *thePoint2.x;
+ double dy = *thePoint1.y - *thePoint2.y;
+ return dx * dx + dy * dy;
+}
+
+static bool hasSamePoint(const std::set<EntityWrapperPtr>& theList, const GCS::Point& thePoint)
+{
+ std::set<EntityWrapperPtr>::const_iterator anIt = theList.begin();
+ for (; anIt != theList.end(); ++anIt)
+ if (squareDistance(thePoint, toPoint(*anIt)) < 1.e-14)
+ return true;
+ return false;
+}
+
+bool hasSamePoint(const std::set<EntityWrapperPtr>& theList,
+ const EntityWrapperPtr& thePoint)
+{
+ return hasSamePoint(theList, toPoint(thePoint));
+}
+
+
+PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::CoincidentEntities(
+ const EntityWrapperPtr& theEntity1,
+ const EntityWrapperPtr& theEntity2)
+{
+ add(theEntity1);
+ add(theEntity2);
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::add(
+ const EntityWrapperPtr& theEntity)
+{
+ bool isAdded = true;
+ if (theEntity->type() == ENTITY_POINT) {
+ if (theEntity->isExternal()) {
+ isAdded = !hasSamePoint(myExternalPoints, theEntity);
+ myExternalPoints.insert(theEntity);
+ } else
+ myPoints.insert(theEntity);
+ } else
+ myFeatures.insert(theEntity);
+ return isAdded;
+}
+
+void PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::remove(
+ const EntityWrapperPtr& theEntity)
+{
+ if (theEntity->type() == ENTITY_POINT) {
+ if (theEntity->isExternal())
+ myExternalPoints.erase(theEntity);
+ else
+ myPoints.erase(theEntity);
+ } else
+ myFeatures.erase(theEntity);
+}
+
+void PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::merge(
+ const CoincidentEntities& theOther)
+{
+ myExternalPoints.insert(theOther.myExternalPoints.begin(), theOther.myExternalPoints.end());
+ myPoints.insert(theOther.myPoints.begin(), theOther.myPoints.end());
+ myFeatures.insert(theOther.myFeatures.begin(), theOther.myFeatures.end());
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isExist(
+ const EntityWrapperPtr& theEntity) const
+{
+ if (theEntity->type() == ENTITY_POINT) {
+ if (theEntity->isExternal())
+ return myExternalPoints.find(theEntity) != myExternalPoints.end();
+ else
+ return myPoints.find(theEntity) != myPoints.end();
+ }
+
+ return myFeatures.find(theEntity) != myFeatures.end();
+}
+
+bool PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::isExist(
+ const GCS::Point& thePoint) const
+{
+ return hasSamePoint(myExternalPoints, thePoint) || hasSamePoint(myPoints, thePoint);
+}
+
+EntityWrapperPtr PlaneGCSSolver_UpdateCoincidence::CoincidentEntities::externalPoint() const
+{
+ return myExternalPoints.empty() ? EntityWrapperPtr() : *myExternalPoints.begin();
+}