You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
5.2 KiB

13 years ago
13 years ago
13 years ago
  1. //----------------------------------------------------------------------------
  2. //
  3. // Copyright (C) 2004-2025 by EMGU Corporation. All rights reserved.
  4. //
  5. //----------------------------------------------------------------------------
  6. /*
  7. #include "plane3D.h"
  8. void setPlane3D(Plane3D* plane, const CvPoint3D64f* unitNormal, const CvPoint3D64f* pointInPlane)
  9. {
  10. memcpy(&plane->unitNormal, unitNormal, sizeof(CvPoint3D64f));
  11. plane->p = - cvPoint3D64fDotProduct(unitNormal, pointInPlane);
  12. }
  13. double pointToPlane3DSignedDistance(const CvPoint3D64f* point, const Plane3D* plane)
  14. {
  15. return cvPoint3D64fDotProduct(point, &plane->unitNormal) + plane->p;
  16. }
  17. bool computePlane3DIntersection(Plane3D* plane0, Plane3D* plane1, Plane3D* plane2, CvPoint3D64f* intersectionPoint)
  18. {
  19. cv::Mat_<double> left(3, 3);
  20. memcpy(left.ptr<double>(0), plane0, 3 * sizeof(double));
  21. memcpy(left.ptr<double>(1), plane1, 3 * sizeof(double));
  22. memcpy(left.ptr<double>(2), plane2, 3 * sizeof(double));
  23. cv::Mat_<double> right(3, 1);
  24. double* rightPtr = right.ptr<double>();
  25. *rightPtr++ = -plane0->p;
  26. *rightPtr++ = -plane1->p;
  27. *rightPtr++ = -plane2->p;
  28. cv::Mat_<double> intersection(3, 1);
  29. if (cv::solve(left, right, intersection))
  30. {
  31. memcpy( intersectionPoint, intersection.ptr<double>(), 3 * sizeof(double));
  32. return true;
  33. } else
  34. return false;
  35. }
  36. void setEdge3D(Edge3D* edge, const CvPoint3D64f* start, const CvPoint3D64f* end)
  37. {
  38. memcpy(&edge->startPoint, start, sizeof(CvPoint3D64f));
  39. cvPoint3D64fSub(end, start, &edge->delta);
  40. }
  41. bool computeEdge3DPlane3DIntersection(Edge3D* edge, Plane3D* plane, CvPoint3D64f* intersection)
  42. {
  43. double denominator = cvPoint3D64fDotProduct(&plane->unitNormal, &edge->delta);
  44. if (denominator == 0) return false;
  45. double numerator = plane->p - cvPoint3D64fDotProduct(&plane->unitNormal, &edge->startPoint);
  46. double fraction = numerator / denominator;
  47. if ( fraction < 0 || fraction > 1) return false;
  48. intersection->x = edge->startPoint.x + fraction*edge->delta.x;
  49. intersection->y = edge->startPoint.y + fraction*edge->delta.y;
  50. intersection->z = edge->startPoint.z + fraction*edge->delta.z;
  51. return true;
  52. }
  53. void computePlane3DCuboidIntersection(Plane3D* plane, CvPoint3D64f* center, CvPoint3D64f* size, std::vector<CvPoint3D64f>& intersections)
  54. {
  55. std::vector<CvPoint3D64f> vertices;
  56. CvPoint3D64f halfSize;
  57. cvPoint3D64fMul(size, 0.5, &halfSize);
  58. vertices.push_back(cvPoint3D64f(center->x - halfSize.x, center->y - halfSize.y, center->z - halfSize.z));
  59. vertices.push_back(cvPoint3D64f(center->x - halfSize.x, center->y - halfSize.y, center->z + halfSize.z));
  60. vertices.push_back(cvPoint3D64f(center->x - halfSize.x, center->y + halfSize.y, center->z - halfSize.z));
  61. vertices.push_back(cvPoint3D64f(center->x - halfSize.x, center->y + halfSize.y, center->z + halfSize.z));
  62. vertices.push_back(cvPoint3D64f(center->x + halfSize.x, center->y - halfSize.y, center->z - halfSize.z));
  63. vertices.push_back(cvPoint3D64f(center->x + halfSize.x, center->y - halfSize.y, center->z + halfSize.z));
  64. vertices.push_back(cvPoint3D64f(center->x + halfSize.x, center->y + halfSize.y, center->z - halfSize.z));
  65. vertices.push_back(cvPoint3D64f(center->x + halfSize.x, center->y + halfSize.y, center->z + halfSize.z));
  66. std::vector<Edge3D> edges;
  67. Edge3D edge;
  68. setEdge3D(&edge, &vertices[0], &vertices[1]); edges.push_back(edge);
  69. setEdge3D(&edge, &vertices[1], &vertices[3]); edges.push_back(edge);
  70. setEdge3D(&edge, &vertices[3], &vertices[2]); edges.push_back(edge);
  71. setEdge3D(&edge, &vertices[2], &vertices[0]); edges.push_back(edge);
  72. setEdge3D(&edge, &vertices[0], &vertices[4]); edges.push_back(edge);
  73. setEdge3D(&edge, &vertices[1], &vertices[5]); edges.push_back(edge);
  74. setEdge3D(&edge, &vertices[3], &vertices[7]); edges.push_back(edge);
  75. setEdge3D(&edge, &vertices[2], &vertices[6]); edges.push_back(edge);
  76. setEdge3D(&edge, &vertices[4], &vertices[5]); edges.push_back(edge);
  77. setEdge3D(&edge, &vertices[5], &vertices[7]); edges.push_back(edge);
  78. setEdge3D(&edge, &vertices[7], &vertices[6]); edges.push_back(edge);
  79. setEdge3D(&edge, &vertices[6], &vertices[4]); edges.push_back(edge);
  80. //std::vector<CvPoint3D64f> intersections;
  81. CvPoint3D64f c = cvPoint3D64f(0, 0, 0);
  82. for(unsigned int i = 0; i < edges.size(); i++)
  83. {
  84. CvPoint3D64f intersection;
  85. if(computeEdge3DPlane3DIntersection(&edges[i], plane, &intersection))
  86. {
  87. intersections.push_back(intersection);
  88. c.x += intersection.x;
  89. c.y += intersection.y;
  90. c.z += intersection.z;
  91. }
  92. }
  93. if (intersections.size() <= 1) return;
  94. c.x /= intersections.size();
  95. c.y /= intersections.size();
  96. c.z /= intersections.size();
  97. CvPoint3D64f nor0;
  98. CvPoint3D64f nor1;
  99. CvPoint3D64f crossProduct;
  100. for (unsigned int i = 1; i < intersections.size(); i++)
  101. {
  102. for (int j = i; j > 0; j--)
  103. {
  104. cvPoint3D64fSub(&intersections[j-1], &c, &nor0);
  105. cvPoint3D64fSub(&intersections[j], &c, &nor1);
  106. cvPoint3D64fCrossProduct(&nor0, &nor1, &crossProduct);
  107. bool sameSide = cvPoint3D64fDotProduct(&crossProduct, &plane->unitNormal) >= 0;
  108. if (sameSide) break;
  109. std::swap(intersections[j-1], intersections[j]);
  110. }
  111. }
  112. }
  113. */