zoukankan      html  css  js  c++  java
  • [综] 判断两向量夹角是否大于180°即0~360°

    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

  • 相关阅读:
    (转)使用InfluxDB+cAdvisor+Grafana配置Docker监控
    Linux cut命令
    php 三种数组
    Linux httpd源码编译安装
    Linux yum如何下载rpm包到本地
    linux yum 工具
    windows phpstudy 本地添加自定义域名
    php.ini
    Linux rpm 查询
    linux rpm 安装和卸载
  • 原文地址:https://www.cnblogs.com/xfzhang/p/2963644.html
Copyright © 2011-2022 走看看