一 前言

1.概述

    主要概述了点乘,叉乘的实用例子,没有讲述什么原理性的,偏向应用层。点乘叉乘数学原理性的东西比较“难记”,网上很多。实用举例,网上算是比较少吧。故,来总结一番。

2.可以解决的问题

    I.如何计算角度

    II.如何判断前后

    III.如何判断逆时针还是顺时针。

    IV.如何判断其他物体在目标物体左右。

    V.如何计算平行四边形面积

二 理论知识

1.点乘性质

       a · b = |a|*|b| cosθ

        a ·b = b·a

        结果是float类型

2.叉乘性质

         aXb = c,c⊥a,c⊥b。

         |aXb| = |a| |b| sinθ,

       a X b = -b X a

       叉乘的结果还是向量,且其模就是那两个向量为边的平行四边形面积

3.性质总结

      根据点乘,叉乘的公式得知,用到cos函数和sin函数,所以理解cos函数和sin函数很重要。

复习一下,我推荐使用根据函数图像理解。

  点乘,cos函数

      

  叉乘,sin函数

      

三.分析&理解

     当然,这边计算角度,直接可以用Vector.Angle(p1,p2) 就可以解决,但是返回角度范围为(0,180)。

  我们根据上述点乘叉乘,可以得出,点乘,叉乘都可以算出角度。

1.点乘 计算角度

           首先我们根据公式   a · b = |a|*|b| cosθ,θ∈(0,180) 

      I.在知道a,b均为单位向量的情况,则 cosθ = Mathf.Dot(a,b)这里的θ角度跟Vector.Angle的返回的结果是一致的(0,180),则cosθ最终返回的也只是 (-1,1)之间.

      II.继续得出 θ =arcCos(Mathf.Dot(a,b)) ---------注意这个θ是弧度值,弧度制就类似π/2, 90度。

      III.我们的目的是得出角度,则 angle = θ * Mathf.Rad2Deg     ----------注意:Mathf.Rad2Deg即为 180/π,与之相乘则弧度转角度;  注意区分Mathf.Deg2Rad 为π/180,角度转弧度,Deg即Degree,角度的意思。      

      float cosAngle = Vector3.Dot(p1.normalized, p2.normalized);
float angleDot = Mathf.Acos(cosAngle)*Mathf.Rad2Deg;
float angleVector = Vector3.Angle(p1, p2); Debug.Log("angleDot:" + angleDot);
Debug.Log("angleVector:" + angleVector);

      由上述对比,完全与Vector.Angle一致,结果都是0,180范围。

2.点乘计算背向还是面向   

    根据上述1中结果,可以使用其判断是面向还是背向,点乘结果>0, θ∈0,,90)则面向;

点乘结果<0,θ∈90,180,则背向。

3.叉乘计算角度

    我们根据公式 |aXb| = |a|*|b|*sin<θ>

     I.当然,我们只需要计算角度,还是需要转为单位向量计算最为方便,得出|aXb| = sin<θ>

     II.则得出,θ = ARCSin(|aXb|), (Mathf.Magnitude,这是求向量长度)

     III.因为上述得出的是弧度制,依然 则 angle = Mathf.arcSin(|aXb|) *Mathf.Rad2Deg      

      Vector3 corssResult = Vector3.Cross(p1.normalized, p2.normalized);
    float angleCross = Mathf.Asin(Vector3.Magnitude(corssResult)) * Mathf.Rad2Deg;
    Debug.Log("angleCross:" + angleCross);
    Debug.Log("angleVector:" + angleVector);

由上述对比得出angleCross 范围在(0,90),即两个向量间的延伸交叉最小的夹角,这个真的有点出乎意料,需要自己注意一下。

这个应用啥呐,应用“两个向量不考虑方向的情况之间谁更紧密”吧。

4.如何判断逆时针还是顺时针

  (因为根据1 点乘中得出的角度,范围都只是0,180,并还不能清楚知道两个向量的具体方位,所以还缺个顺时针还是逆时针。)

   我们可以根据叉乘的性质 a X b  = - b X a ,可以根据叉乘的正负值,来判断a,b的相对位置,即b是出于a的顺时针还是逆时针。

这里需要注意“叉乘的正负值”:注意顺时针,逆时针的概念,是在2d空间中判断,所以需要指定两个维度,一般在x,y屏幕上,则判断z轴上的正负,即为“叉乘的正负值”。   

        Vector3 resultCross = Vector3.Cross(p1, p2);
//在指定x,y平面则判断z轴正负,为正,则p2在p1顺时针,为负,则p2在p1逆时针。
Debug.Log("p1:"+p1+" p2:"+p2 +"resultCross.z:" + resultCross.z);

5.如何判断物体在左边还是右边

  其实判断在左边还是在右边,理论与4相似,只是需要稍微加工一下。假设p1为目标点,p2判断是在p1的左边还是右边。

见图:

    

         //因为我们是在xy平面上,所以判断z轴
var crossResult = Vector3.Cross(Vector3.up,p2-p1).z;
//Vector3.Cross(trans1.up, trans2.position - trans1.position).z; //transform的写法
Debug.Log("crossResult:" + crossResult);

crossResult 为正则在其左边,为负则在其右边。也4中顺时针,逆时针一个道理,只不过对比的是物体的正前方的向量。

注意如果为0,则是物体正前方,或者正后方;判断正后方还是正前方参考2中用法。

6.如何计算出两向量组成的平行四边形面积

    根据平行四边形公式  S=a*h,h为高,a为底。

    a = |p1|

    又因为h = |p2|*sinθ,则 a* h = |p1|*|p2|*sinθ

    即 |p1Xp2| = S

       float s = Vector3.Magnitude(resultCross);   

7.光照强度应用

    通过对任意平面的任意两个向量进行插乘,得到该平面的法向量。然后通过光照向量和法向量进行点乘,计算出光照强度。

光照强度:光向量与平面越垂直就所受光照强度越大,即法向量与光照向量重合。反之如果光照向量与平面平行,则该面所有那个光的强度越弱。

(注意叉乘计算出的法向量方向根据右手定则)

四 总结

    上述基本涵盖了游戏中的点乘叉乘的所有用法,都是自己敲一遍论证后的结果,当然,还需要你自己敲一遍,如有讲述错误,欢迎指正。

哎,这是2018年唯一一篇比较原创花心思的博客,不能这样啦,博客要坚持写,代码要亲自敲啊。

Unity 点乘&叉乘 应用实例的更多相关文章

  1. 关于Unity中顶点片元Shader实例

    补充 float4 fixed4 _Time 1: float4是内置向量 (x, y, z, w); float4 a; 访问单独成员a.x, a.y, a.z, a.w;2: fixed4 是内置 ...

  2. Unity中下载和本地保存实例

    原地址:http://www.linuxidc.com/Linux/2011-10/45888.htm Download.cs using UnityEngine; using System.Coll ...

  3. Microsoft.Practices.Unity入门

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  4. WPF PRISM开发入门二(Unity依赖注入容器使用)

    这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...

  5. unity集成openinstall流程

    目的 1.Unity集成openinstall sdk? 最近在使用一个叫openinstall的SDK,通过它实现免填邀请码的功能,集成到unity游戏开发中.对App安装流程的优化,尤其是免填写邀 ...

  6. Unity文档阅读 第三章 依赖注入与Unity

    Introduction 简介In previous chapters, you saw some of the reasons to use dependency injection and lea ...

  7. [Unity优化]批处理04:MaterialPropertyBlock

    参考链接: https://blog.csdn.net/liweizhao/article/details/81937590 1.在场景中放一些Cube,赋予一个新材质,使用内置shader(Unli ...

  8. 微软企业库Unity学习笔记

    本文主要介绍: 关于Unity container配置,注册映射关系.类型,单实例.已存在对象和指出一些container的基本配置,这只是我关于Unity的学习心得和笔记,希望能够大家多交流相互学习 ...

  9. python基础(9)--递归、二叉算法、多维数组、正则表达式

    1.递归 在函数内部,可以调其他函数,如果一个函数在内部调用它本身,这个函数就是递归函数.递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于裂解 递归算法解决问题的特点: 1)递归是 ...

随机推荐

  1. 20175305张天钰《java程序设计》第七周学习总结

    <java程序设计>第七周学习总结 第八章 常用实用类 1.String类 1.String类不可以有子类. 2.用户无法输出String对象的引用,输出的是字符序列 3.构造方法:Str ...

  2. xxl-job调度中心配置以及常见错误

    项目结构图 启动步骤: 1.检查 /xxl-job/xxl-job-admin/src/main/resources/xxl-job-admin.properties 下的JDBC链接.登录账号. 2 ...

  3. hadoop2-HBase的Java API操作

    Hbase提供了丰富的Java API,以及线程池操作,下面我用线程池来展示一下使用Java API操作Hbase. 项目结构如下: 我使用的Hbase的版本是 hbase-0.98.9-hadoop ...

  4. vuex的一些学习

    刚开始学vuex看文档看的一脸懵逼,故而网上各种查找资料,视频去观看学习,虽然看了很多还是很蒙圈,最近看了一个讲vuex的视频还有一个 类似的简书文档从中学到了很多,慢慢理清了头绪,至此记录一下,共同 ...

  5. python学习:输入设置

    输入设置 输入用户名和密码 代码: _user = "alex"_password = "abc123" username = input("User ...

  6. webpack学习--安装

    webpack需要在node环境运行,可以去node官网进行下载安装包:http://nodejs.cn/download/ 1.打开cmd命令窗口,运行node -v 2.全局安装webpack:n ...

  7. java常用框架

    一.SpringMVC http://blog.csdn.net/evankaka/article/details/45501811 Spring Web MVC是一种基于Java的实现了Web MV ...

  8. golang二进制bit位的常用操作

    golang作为一热门的兼顾性能 效率的热门语言,相信很多人都知道,在编程语言排行榜上一直都是很亮眼,作为一门强类型语言,二进制位的操作肯定是避免不了的,数据的最小的单位也就是位,尤其是网络中封包.拆 ...

  9. PHP实现微信模板消息发送给指定用户

    使用公众号的模板消息功能,必须是认证过的服务号,需要发送微信号的openid,同一微信号在不同公众号下的openid是不同的,在公众号下是唯一的,获取不到微信号 进入公众平台  功能->模板消息 ...

  10. c# 通过MailHelper发送QQ邮件

    发送的方法 appsetting内容 第一个是发送邮件qq账号,第二个是QQ邮箱的POP3/SMTP服务码(下面会说怎么获取),第三个是服务器,第四个是端口 获取QQ邮箱的POP3/SMTP服务码 1 ...