当前位置:   article > 正文

OpenCV/C++:点线面相关计算_线面相交的点 代码计算

线面相交的点 代码计算

之前也有一篇笔记,都比较简单,做个记录,方便速查。

C++&OpenCV:三角形插值、线面的交点_六月的翅膀的博客-CSDN博客


目录

1、向量的模

2、两点间距离(两点间的向量模) 

 3、求线段中某点坐标

 4、叉乘,平面法向量

 5、线面交点

6、空间点到直线的距离

7、平面方程

8、两直线的交点

9、两向量的夹角


1、向量的模

  1. int main()
  2. {
  3. Vec3f A = Vec3f(10, 10, 1);
  4. cout << "向量A的模 = " << norm(A) << endl;
  5. Vec3f B = Vec3f(3, 3, 1);
  6. cout << "向量B的模 = " << norm(B) << endl;
  7. return 0;
  8. }

 

2、两点间距离(两点间的向量模) 

  1. int main()
  2. {
  3. Vec3f A = Vec3f(10, 10, 1);
  4. Vec3f B = Vec3f(3, 3, 1);
  5. cout << "线段AB的长度为 = " << norm(A - B) << endl;
  6. //结果为6*根2
  7. return 0;
  8. }

 3、求线段中某点坐标

  1. int main()
  2. {
  3. Vec3f A = Vec3f(0, 10, 0);
  4. Vec3f B = Vec3f(0, 0, 0);
  5. Vec3f C = Vec3f(10, 0, 0);
  6. Vec3f M = Vec3f(3, 0, 0);
  7. float t = norm(M - C) / norm(B - C);
  8. Vec3f N = C + (A - C) * t;
  9. cout << "N点坐标为:" << N << endl;
  10. return 0;
  11. }

 

 4、叉乘,平面法向量

上面图中写错了,ON = OB.cross(OA)。右手定则

不仅点和叉写错了 方向还错了 /dog

 5、线面交点

  1. int main()
  2. {
  3. //需要知道直线上一点和其方向向量,平面一点及其法向量
  4. Vec3f A=Vec3f(0, 1, 1);
  5. Vec3f B=Vec3f(1, 0, 1);
  6. Vec3f O=Vec3f(0, 0, 0);
  7. Vec3f M=Vec3f(1, 1, 0);
  8. Vec3f N=Vec3f(0, 0, 1);
  9. Vec3f line = M-N;//线方向向量,这里谁减谁都行
  10. Vec3f plane = (A - O).cross(B - O);//平面两个向量叉乘就是法向量
  11. float den = plane.dot(line);//面法向量乘线方向向量
  12. float t = plane.dot(A - N) / den;//A是面上一点,用B也可以
  13. Vec3f p0 = N + line * t;//这里线上的点用的N,也可以用M,只要上面求t的时候也是用的M就可以
  14. cout << p0 << endl;
  15. return 0;
  16. }

 


//2023年1月10日 update

//2023年10月27日

 

  1. cv::Point3d pointOfLinePlaneSolve(Point3d L_p, Point3d L_dir, Point3d P_p, Point3d P_norm)
  2. {
  3. //这种方法要求线的方向向量的yz值不能为0,因为涉及到除法
  4. Mat x = (cv::Mat_<double>(3, 3) << P_norm.x, P_norm.y, P_norm.z,
  5. 1, -L_dir.x / L_dir.y, 0,
  6. 1, 0, -L_dir.x / L_dir.z);
  7. Mat y = (cv::Mat_<double>(3, 1) << P_norm.dot(P_p),
  8. L_p.x - L_dir.x / L_dir.y * L_p.y,
  9. L_p.x - L_dir.x / L_dir.z * L_p.z
  10. );
  11. // 使用solve函数求解方程
  12. Mat coef;
  13. solve(x, y, coef, DECOMP_QR);
  14. return Point3d(coef);
  15. }

6、空间点到直线的距离

  1. /// <summary>
  2. ///
  3. /// </summary>
  4. /// <param name="P">线外一点</param>
  5. /// <param name="A">线上点</param>
  6. /// <param name="B">线上点</param>
  7. /// <returns></returns>
  8. float getDist_P2L(Vec3f P, Vec3f A, Vec3f B)
  9. {
  10. Vec3f PA = P - A;//线外点到线上一点的向量
  11. Vec3f Ldir = B - A;//直线的方向向量
  12. Vec3f Pnorm = PA.cross(Ldir);
  13. float S1 = norm(Ldir);
  14. float S2 = norm(Pnorm);
  15. return S2 / S1;
  16. }
  17. int main()
  18. {
  19. Vec3f A = Vec3f(1.0, 0, 0);
  20. Vec3f B = Vec3f(0.0, 1.0, 0);
  21. Vec3f P = Vec3f(0.5, 0.5, 3);
  22. float dis = getDist_P2L(P, A, B);
  23. cout << dis << endl;
  24. }

//2023年1月12日 update

7、平面方程

  1. vector<Vec3f> input;
  2. vector<float> coeffi;
  3. void GetPanelEquation(vector<Vec3f>& point3fArray)
  4. {
  5. if (point3fArray.size() < 3)
  6. {
  7. cerr << "GetPanelEquation(...)函数中输入点的数量小于3." << endl;
  8. }
  9. float a,b,c,d;
  10. a = (point3fArray[1][1] - point3fArray[0][1])*(point3fArray[2][2] - point3fArray[0][2]) -
  11. (point3fArray[1][2] - point3fArray[0][2])*(point3fArray[2][1] - point3fArray[0][1]);
  12. b = (point3fArray[1][2] - point3fArray[0][2])*(point3fArray[2][0] - point3fArray[0][0]) -
  13. (point3fArray[1][0] - point3fArray[0][0])*(point3fArray[2][2] - point3fArray[0][2]);
  14. c = (point3fArray[1][0] - point3fArray[0][0])*(point3fArray[2][1] - point3fArray[0][1]) -
  15. (point3fArray[1][1] - point3fArray[0][1])*(point3fArray[2][0] - point3fArray[0][0]);
  16. d = 0 - (a * point3fArray[0][0] + b*point3fArray[0][1] + c*point3fArray[0][2]);
  17. coeffi.push_back(a);
  18. coeffi.push_back(b);
  19. coeffi.push_back(c);
  20. coeffi.push_back(d);
  21. }
  22. int main()
  23. {
  24. input.push_back(Vec3f(100, 0, 0));
  25. input.push_back(Vec3f(0, 100, 0));
  26. input.push_back(Vec3f(0, 0, 3));
  27. GetPanelEquation(input);
  28. cout << "平面方程为:"<< endl << coeffi[0] << " X + " << coeffi[1] << " Y + " << coeffi[2] << " Z + " << coeffi[3] << " = 0" << endl;
  29. if (abs(coeffi[3])>1e-6)
  30. {
  31. cout << "平面方程为:" << endl << -coeffi[0] / coeffi[3] << " X + " << -coeffi[1] / coeffi[3] << " Y + " << -coeffi[2] / coeffi[3] << " Z = 1" << endl;
  32. }
  33. return 1;
  34. }

8、两直线的交点

  1. double r_xy12 = PointOnLine[0].x * PointOnLine[1].y - PointOnLine[1].x * PointOnLine[0].y;
  2. double r_x12 = PointOnLine[0].x - PointOnLine[1].x;
  3. double r_xy34 = PointOnLine[2].x * PointOnLine[3].y - PointOnLine[3].x * PointOnLine[2].y;
  4. double r_x34 = PointOnLine[2].x - PointOnLine[3].x;
  5. double r_y12 = PointOnLine[0].y - PointOnLine[1].y;
  6. double r_y34 = PointOnLine[2].y - PointOnLine[3].y;
  7. double fenmu = r_x12 * r_y34 - r_y12 * r_x34;
  8. GridPoint[i].x = (r_xy12 * r_x34 - r_x12 * r_xy34) / fenmu;
  9. GridPoint[i].y = (r_xy12 * r_y34 - r_y12 * r_xy34) / fenmu;

  1. struct LinePara
  2. {
  3. float k;
  4. float b;
  5. };
  6. // 获取直线参数
  7. void getLinePara(float& x1, float& y1, float& x2, float& y2, LinePara& LP)
  8. {
  9. double m = 0;
  10. // 计算分子
  11. m = x2 - x1;
  12. if (0 == m)
  13. {
  14. LP.k = 10000.0;
  15. LP.b = y1 - LP.k * x1;
  16. }
  17. else
  18. {
  19. LP.k = (y2 - y1) / (x2 - x1);
  20. LP.b = y1 - LP.k * x1;
  21. }
  22. }
  23. // 获取交点
  24. bool getCross(Point2f& p1, Point2f& p2, Point2f& p3, Point2f& p4, Point2f& pt) {
  25. LinePara para1, para2;
  26. getLinePara(p1.x, p1.y, p2.x, p2.y, para1);
  27. getLinePara(p3.x, p3.y, p4.x, p4.y, para2);
  28. pt.x = (para2.b - para1.b) / (para1.k - para2.k);
  29. pt.y = para1.k * pt.x + para1.b;
  30. // 判断是否平行
  31. if (abs(para1.k - para2.k) > 0.5)
  32. {
  33. pt.x = (para2.b - para1.b) / (para1.k - para2.k);
  34. pt.y = para1.k * pt.x + para1.b;
  35. return true;
  36. }
  37. else
  38. {
  39. return false;
  40. }
  41. }

9、两向量的夹角

  1. template <typename DataType>
  2. double getAngle3d(DataType _in1, DataType _in2)
  3. {
  4. double theta2 = acos(_in1.dot(_in2) / (norm(_in1) * norm(_in2)));
  5. if (abs(_in1.dot(_in2)-1)<10e-6)//这里做个判断,否则nan
  6. {
  7. theta2 = 0;
  8. }
  9. else
  10. {
  11. theta2 = theta2 * 180 / acos(-1);
  12. }
  13. return theta2;
  14. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/423037
推荐阅读
相关标签
  

闽ICP备14008679号