| 1414 | } |
| 1415 | |
| 1416 | b3ConvexHullInternal::Edge* b3ConvexHullInternal::findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot) |
| 1417 | { |
| 1418 | Edge* minEdge = NULL; |
| 1419 | |
| 1420 | #ifdef DEBUG_CONVEX_HULL |
| 1421 | b3Printf("find max edge for %d\n", start->point.index); |
| 1422 | #endif |
| 1423 | Edge* e = start->edges; |
| 1424 | if (e) |
| 1425 | { |
| 1426 | do |
| 1427 | { |
| 1428 | if (e->copy > mergeStamp) |
| 1429 | { |
| 1430 | Point32 t = *e->target - *start; |
| 1431 | Rational64 cot(t.dot(sxrxs), t.dot(rxs)); |
| 1432 | #ifdef DEBUG_CONVEX_HULL |
| 1433 | b3Printf(" Angle is %f (%d) for ", (float)b3Atan(cot.toScalar()), (int)cot.isNaN()); |
| 1434 | e->print(); |
| 1435 | #endif |
| 1436 | if (cot.isNaN()) |
| 1437 | { |
| 1438 | b3Assert(ccw ? (t.dot(s) < 0) : (t.dot(s) > 0)); |
| 1439 | } |
| 1440 | else |
| 1441 | { |
| 1442 | int cmp; |
| 1443 | if (minEdge == NULL) |
| 1444 | { |
| 1445 | minCot = cot; |
| 1446 | minEdge = e; |
| 1447 | } |
| 1448 | else if ((cmp = cot.compare(minCot)) < 0) |
| 1449 | { |
| 1450 | minCot = cot; |
| 1451 | minEdge = e; |
| 1452 | } |
| 1453 | else if ((cmp == 0) && (ccw == (getOrientation(minEdge, e, s, t) == COUNTER_CLOCKWISE))) |
| 1454 | { |
| 1455 | minEdge = e; |
| 1456 | } |
| 1457 | } |
| 1458 | #ifdef DEBUG_CONVEX_HULL |
| 1459 | b3Printf("\n"); |
| 1460 | #endif |
| 1461 | } |
| 1462 | e = e->next; |
| 1463 | } while (e != start->edges); |
| 1464 | } |
| 1465 | return minEdge; |
| 1466 | } |
| 1467 | |
| 1468 | void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1) |
| 1469 | { |