Vector3f.cpp
上传用户:jsylhbnbhn
上传日期:2013-11-03
资源大小:119k
文件大小:4k
源码类别:

OpenCV

开发平台:

Visual C++

  1. /***************************************************************************
  2.                           vector3f.cpp  -  description
  3.                              -------------------
  4.     begin                : Thu Apr 10 2003
  5.     copyright            : (C) 2003 by junglesong
  6.     email                : junglesong@etang.com
  7.  ***************************************************************************/
  8. #include "vector3f.h"
  9. #include <math.h>
  10. //得到两向量的叉乘
  11. /* 有关叉乘的说明(文字出处:http://www.gameres.com/Articles/Program/Visual/Other/shiliang.htm)
  12. 叉乘:Vector1(x1,y1,z1),Vector2(x2,y2,z2):
  13. 其结果是个矢量.
  14. 方向是Vector1,Vector2构成的平面法线.再使用右手定则
  15. 长度是Length(Vector1)*Length(Vector2)*sin(theta)
  16. theta是Vector1 & Vector2的夹角.
  17. 所以,平行的矢量叉乘结果为0矢量(长为0,方向任意)
  18. 计算结果矢量:(ox,oy,oz)
  19. ox = (y1 * z2) - (y2 * z1)
  20. oy = (z1 * x2) - (z2 * x1)
  21. oz = (x1 * y2) - (x2 * y1)
  22. 用途:计算法向量
  23. */
  24. Vector3f Cross(Vector3f vVector1, Vector3f vVector2)
  25. {
  26. //定义一个容纳叉乘结果的向量
  27. Vector3f vNormal;
  28. //得到此向量在X轴上的投影值
  29. vNormal.x = ((vVector1.y * vVector2.z) - (vVector1.z * vVector2.y));
  30. //得到此向量在Y轴上的投影值
  31. vNormal.y = ((vVector1.z * vVector2.x) - (vVector1.x * vVector2.z));
  32. //得到此向量在Z轴上的投影值
  33. vNormal.z = ((vVector1.x * vVector2.y) - (vVector1.y * vVector2.x));
  34. //返回此向量
  35. return vNormal;
  36. }
  37. //得到一个向量的绝对长度
  38. float Magnitude(Vector3f vNormal)
  39. {
  40. return (float)sqrt( (vNormal.x * vNormal.x) + (vNormal.y * vNormal.y) + (vNormal.z * vNormal.z) );
  41. }
  42. //将一个向量单位化
  43. Vector3f Normalize(Vector3f vNormal)
  44. {
  45. //得到此向量的绝对长度
  46. float magnitude = Magnitude(vNormal);
  47. //让每个分量分别除以此长度
  48. vNormal.x /= magnitude;
  49. vNormal.y /= magnitude;
  50. vNormal.z /= magnitude;
  51. //返回此向量
  52. return vNormal;
  53. }
  54. //得到一个三点决定的平面的垂直向量(经过单位化)
  55. Vector3f Normal(Vector3f vPolygon[])
  56. {
  57. //得到两条边的向量
  58. Vector3f vVector1 = vPolygon[2] - vPolygon[0];
  59. Vector3f vVector2 = vPolygon[1] - vPolygon[0];
  60. //得到这两向量的叉乘
  61. Vector3f vNormal = Cross(vVector1, vVector2);
  62. //单位化
  63. vNormal.x = Normalize(vNormal).x;
  64. vNormal.y = Normalize(vNormal).y;
  65. vNormal.z = Normalize(vNormal).z;
  66. //返回此变量
  67. return vNormal;
  68. }
  69. //得到两点间的距离
  70. float Distance(Vector3f vPoint1, Vector3f vPoint2)
  71. {
  72. double distance = sqrt( (vPoint2.x - vPoint1.x) * (vPoint2.x - vPoint1.x) +
  73.     (vPoint2.y - vPoint1.y) * (vPoint2.y - vPoint1.y) +
  74.     (vPoint2.z - vPoint1.z) * (vPoint2.z - vPoint1.z) );
  75. return (float)distance;
  76. }
  77. //得到两向量的点积
  78. /*有关点积的说明(文字出处:http://www.gameres.com/Articles/Program/Visual/Other/shiliang.htm)
  79. 两个矢量的点积是个标量.
  80. 中学物理的力做功就是矢量点积的例子:W=|F|.|S|.cos(theta)
  81. 二矢量点积:
  82. Vector1:(x1,y1,z1) Vector2(x2,y2,z2)
  83. DotProduct=x1*x2+y1*y2+z1*z2
  84. 很重要的应用:
  85. 1.求二矢量余弦:
  86. 由我们最熟悉的力做功:
  87. cos(theta)=F.S/(|F|.|S|)
  88. 可以判断二矢量的方向情况: cos=1同向,cos=-1相反,cos=0直角
  89. 曲面消隐(Cull face)时判断物体表面是否可见:(法线和视线矢量的方向问题)cos>0不可见,cos<0可见
  90. OpenGL就是这么做的。
  91. 2.Lambert定理求光照强度也用点积:
  92. Light=K.I.cos(theta)
  93. K,I为常数,theta是平面法线与入射光线夹角
  94. */
  95. float Dot(Vector3f vVector1, Vector3f vVector2)
  96. {
  97. return ( (vVector1.x * vVector2.x) + (vVector1.y * vVector2.y) + (vVector1.z * vVector2.z) );
  98. }
  99. //得到两向量的夹角
  100. double AngleBetweenVectors(Vector3f Vector1, Vector3f Vector2)
  101. {
  102. //得到两向量的点积
  103. float dotProduct = Dot(Vector1, Vector2);
  104. //得到两向量长度的乘积
  105. float vectorsMagnitude = Magnitude(Vector1) * Magnitude(Vector2) ;
  106. //得到两向量夹角
  107. double angle = acos( dotProduct / vectorsMagnitude );
  108. //返回角度值
  109. return( angle );
  110. }