http://huanghs16.bokee.com/2019692.html
求取向量A逆时针到向量B的夹角
算法思路:通过余弦定理求取向量夹角的cosa,然后判断夹角是否大于180,如果大于,则向量夹角为360-arccosa*180/Pi(单位为°);否则夹角为arccosa*180/Pi。(Pi为常量3.14159265)。实验代码如下:
1、先定义Point头文件(Point.h)
# ifndef POINT_H_
# define POINT_H_
class Point
{
public:
Point()
{
x=0.0;
y=0.0;
}
Point(float inx, float iny)
{
x=inx;
y=iny;
}
//析构函数
~Point(){}
float getX() {return x;}
float getY() {return y;}
//重载=操作符,实现两向量变量的赋值
Point operator =(Point& inPoint)
{
Point temp;
temp.x=inPoint.x;
temp.y=inPoint.y;
return temp;
}
//重载+操作符,实现两向量变量的相加
Point operator+(const Point& inPoint)
{
//返回相加的结果
return Point(inPoint.x + x, inPoint.y + y);
}
//重载-操作符,实现两向量变量的相减
Point operator-(const Point& inPoint)
{
//返回相减的结果
return Point(x - inPoint.x, y - inPoint.y);
}
//重载*操作符,实现一个向量变量和一个浮点数的乘法
Point operator*(float num)
{
//返回缩放了的向量
return Point(x * num, y * num);
}
//重载/操作符,实现一个向量变量和一个浮点数的除法
Point operator/(float num)
{
//返回缩放了的向量
return Point(x / num, y / num);
}
//得到一个向量的绝对长度,即距原点的距离
float Length();
private:
float x;
float y;
};
# endif
2、定义相应的cpp文件,并进行算法实验。
# include "point.h"
# include
# include
# include
using namespace std;
const float Pi=3.14159265;
//返回点到原点的距离
float Point::Length()
{
return sqrt(x*x + y*y);
}
//得到两点的距离
float Distance(Point& pPoint1, Point& pPoint2)
{
float subX=pPoint1.getX()-pPoint2.getX();
float subY=pPoint1.getY()-pPoint2.getY();
return sqrt(subX * subX + subY * subY);
}
//得到两向量的点积(即内积)
float DotProduct(Point& pPoint1, Point& pPoint2)
{
return pPoint1.getX() * pPoint2.getX() + pPoint1.getY() * pPoint2.getY();
}
//判断两向量夹角是否大于180°,大于180°返回真,否则返回假
bool AngleLargeThanPi(Point& point1, Point& point2)
{
float temp=point1.getX() * point2.getY() - point2.getX()* point1.getY();
return ( temp < 0);
}
//得到两向量的夹角
float AngleBetweenPoints(Point& pPoint1, Point& pPoint2)
{
float cos_theta = DotProduct(pPoint1,pPoint2) / (pPoint1.Length() * pPoint2.Length());
if( AngleLargeThanPi(pPoint1,pPoint2) )
return 360-acos(cos_theta)*180/Pi;
else
return acos(cos_theta)*180/Pi;
}
//测试程序
int main()
{
Point A(5,0); //可以换不同象限的点,测试夹角。
Point B(-1,-1);
bool largeThanPi = AngleLargeThanPi(A,B);
cout< cout<<"the angle between vector A and B is: "< return 0;
}
如果要投入使用,还需要对边界条件进行处理,添加当向量长度为0时的处理。
点积 叉积
点积的值由以下三个值确定: u的大小v的大小u,v夹角的余弦。在u,v非零的前提下,点积如果为负,则u,v形成的角大于90度;如果为零,那么u,v垂直;如果为正,那么u,v形成的角为锐角。 点积得到两个向量的夹角的cos值,通过它可以知道两个向量的相似性,利用点积可判断一个多边形是否面向摄像机还是背向摄像机
向量的点积与它们夹角的余弦成正比,因此在聚光灯的效果计算中,可以根据点积来得到光照效果,如果点积越大,说明夹角越小,则物理离光照的轴线越近,光照越强。
点积的结果为一个数值。
数值计算方法AB * CD = x3*x4 + y3*y4。
几何意义AB * CD = |AB| * |CD| * cos(a),a为向量AB逆时针转向CD的角度,0<=a<360,也可以认为是两向量的夹角,0<=a<=180。一般用于求夹角,a = acos( (AB * CD) / (|AB| * |CD|) )。也可:|CD| * cos(a) = AB * CD / |AB|,即向量CD在AB上的投影。
>> a=[2 4 5 3 1];
>> b=[3 8 10 12 13];
>> c=dot(a,b)
c =
137
叉积。
叉积的结果为一个向量。
AB×CD数值= x3*y4 – x4*y3。
方向由右手螺旋定则判定。
几何意义:AB×CD = |AB| * |CD| * sin(a),取绝对值即是以AB和CD为边的平行四边形面积。
>> a=[2 3 4];
>> b=[3 4 6];
>> c=cross(a,b)
c =
2 0 -1