Finds the nearest (available) point to an edge \return The nearest point distance (or -1 if no point was found!) **/
| 75 | /** \return The nearest point distance (or -1 if no point was found!) |
| 76 | **/ |
| 77 | static PointCoordinateType FindNearestCandidate(unsigned& minIndex, |
| 78 | const VertexIterator& itA, |
| 79 | const VertexIterator& itB, |
| 80 | const std::vector<Vertex2D>& points, |
| 81 | const std::vector<HullPointFlags>& pointFlags, |
| 82 | PointCoordinateType minSquareEdgeLength, |
| 83 | bool allowLongerChunks = false, |
| 84 | double minCosAngle = -1.0) |
| 85 | { |
| 86 | //look for the nearest point in the input set |
| 87 | PointCoordinateType minDist2 = -1; |
| 88 | const CCVector2 AB = **itB-**itA; |
| 89 | const PointCoordinateType squareLengthAB = AB.norm2(); |
| 90 | const unsigned pointCount = static_cast<unsigned>(points.size()); |
| 91 | |
| 92 | #ifdef CC_CORE_LIB_USES_TBB |
| 93 | tbb::parallel_for( static_cast<unsigned int>(0), pointCount, [&](unsigned int i) { |
| 94 | const Vertex2D& P = points[i]; |
| 95 | if (pointFlags[P.index] != POINT_NOT_USED) |
| 96 | return; |
| 97 | |
| 98 | //skip the edge vertices! |
| 99 | if (P.index == (*itA)->index || P.index == (*itB)->index) |
| 100 | { |
| 101 | return; |
| 102 | } |
| 103 | |
| 104 | //we only consider 'inner' points |
| 105 | const CCVector2 AP = P-**itA; |
| 106 | if (AB.x * AP.y - AB.y * AP.x < 0) |
| 107 | { |
| 108 | return; |
| 109 | } |
| 110 | |
| 111 | //check the angle |
| 112 | if (minCosAngle > -1.0) |
| 113 | { |
| 114 | const CCVector2 PB = **itB - P; |
| 115 | const PointCoordinateType dotProd = AP.x * PB.x + AP.y * PB.y; |
| 116 | const PointCoordinateType minDotProd = static_cast<PointCoordinateType>(minCosAngle * std::sqrt(AP.norm2() * PB.norm2())); |
| 117 | if (dotProd < minDotProd) |
| 118 | { |
| 119 | return; |
| 120 | } |
| 121 | } |
| 122 | |
| 123 | const PointCoordinateType dot = AB.dot(AP); // = cos(PAB) * ||AP|| * ||AB|| |
| 124 | if (dot >= 0 && dot <= squareLengthAB) |
| 125 | { |
| 126 | const CCVector2 HP = AP - AB * (dot / squareLengthAB); |
| 127 | const PointCoordinateType dist2 = HP.norm2(); |
| 128 | if (minDist2 < 0 || dist2 < minDist2) |
| 129 | { |
| 130 | //the 'nearest' point must also be a valid candidate |
| 131 | //(i.e. at least one of the created edges is smaller than the original one |
| 132 | //and we don't create too small edges!) |
| 133 | const PointCoordinateType squareLengthAP = AP.norm2(); |
| 134 | const PointCoordinateType squareLengthBP = (P-**itB).norm2(); |
no test coverage detected