3d图形学基础(一):向量与坐标系

文章目录

    • 1.1 向量与坐标系
      • 1.1.1 向量与坐标系的应用
      • 1.1.2 完整测试代码

1.1 向量与坐标系

1.1.1 向量与坐标系的应用

零向量: 零向量是没有方向的向量;

负向量: 负向量是与原向量方向相反、长度相等的向量;

向量的模: 即向量的长度,向量中各标量的平方和开根可以得到向量的模;

请添加图片描述

/*
* 三维坐标取模
*/
float mod(const Vector3& pos)
{if (*this == VEC3_ZERO)return 0;float squaresSum = x * x + y * y + z * z;return sqrt(squaresSum);
}

单位向量: 长度为1的向量,向量除以向量的模等于该向量的单位向量;

请添加图片描述

/*
* 归一化,获取单位向量
*/
Vector3 normal() const 
{ float tep = mod();if (tep == 0)return VEC3_ZERO;return *this/tep;
}

坐标间的距离: 将两个坐标相减所得到的新坐标进行取模就能得到坐标间的距离;

/*
* 计算与指定坐标的距离
*/
float distance(const Vector3& vec) {Vector3 tep = *this - vec;float distance = tep.mod();return distance;
}
/*
* 计算两个坐标间的距离
*/
inline float Distance(const Vector3& vec1, const Vector3& vec2) {Vector3 tep = vec1 - vec2;float distance = tep.mod();return distance;
}

向量点乘: 向量点乘的结果是一个标量,公式如下;
在这里插入图片描述
在这里插入图片描述

利用向量点乘可以获得两个向量的方向:点乘结果等于 0 两个向量垂直,大于 0 方向相同,小于 0 方向相反;

利用向量点乘还可以获得夹角:

a * b = || a || || b || cosθ => cosθ = (a * b) / (|| a || || b || ) => θ = arccos((a * b) / (|| a || || b || ))

/*
* 点乘
*/
inline float Dot(const Vector3& vec1, const Vector3& vec2) {float result = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;return result;
}
/*
* 计算与指定坐标的夹角
*/
float angle(const Vector3& vec) const{float dot = Dot(*this, vec);float mod1 = mod();float mod2 = vec.mod();if (mod1 == 0.0f || mod2 == 0.0f)return 0.0f;float result = acosf(dot / (mod1 + mod2));return result;
}
/*
* 获取两个向量间的夹角
*/
inline float Angle(const Vector3& vec1, const Vector3& vec2) {float dot = Dot(vec1, vec2);float mod1 = vec1.mod();float mod2 = vec2.mod();if (mod1 == 0.0f || mod2 == 0.0f)return 0.0f;float angle = acosf(dot / (mod1 + mod2));return angle;
}

向量叉乘: 向量叉乘的结果是一个向量,叉乘的结果垂直于进行叉乘的两个向量,公式如下;
在这里插入图片描述
在这里插入图片描述

叉乘获得的结果进行模运算的结果是进行叉乘前的两个向量所映射出的平行四边形的面积;

叉乘还可用来判断两个向量是否平行,如果叉乘结果是零向量则两个向量是平行的;

/*
* 叉乘
*/
inline Vector3 Cross(const Vector3& vec1, const Vector3& vec2) {return Vector3(vec1.y * vec2.z - vec1.z * vec2.y,vec1.z * vec2.x - vec1.x * vec2.z,vec1.x * vec2.y - vec1.y * vec2.x);
}
/*
* 两个向量的方向是否平行
*/
inline bool IsParallel(const Vector3& vec1, const Vector3& vec2) {Vector3 result = Cross(vec1, vec2);return result == VEC3_ZERO;
}
/*
* 计算与指定坐标的方向是否平行
*/
bool isParallel(const Vector3& vec) {Vector3 result = Cross(*this, vec);return result == VEC3_ZERO;
}

1.1.2 完整测试代码

#include <cmath>
#include <sstream>
#ifndef __VECTOR3_H_INCLUDED__
#define __VECTOR3_H_INCLUDED__
class Vector3
{
public:float x, y, z;Vector3() {}Vector3(const Vector3& pos) : x(pos.x), y(pos.y), z(pos.z) {}Vector3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) {}Vector3 operator +() const { return Vector3(fabs(x), fabs(y), fabs(z)); }Vector3 operator -() const { return Vector3(-x, -y, -z); }Vector3 operator +(Vector3 vec) const { return Vector3(x + vec.x, y + vec.y, z + vec.z); }Vector3 operator +=(Vector3 vec) {x += vec.x;y += vec.y;z += vec.z;return *this;}Vector3 operator -(Vector3 vec) const { return Vector3(x - vec.x, y - vec.y, z - vec.z); }Vector3 operator -=(Vector3 vec) {x -= vec.x;y -= vec.y;z -= vec.z;return *this;}Vector3 operator *(float num) const { return Vector3(x * num, y * num, z * num); }Vector3 operator *=(float num) {x *= num;y *= num;z *= num;return *this;}Vector3 operator /(float num) const { float tep = 1.0f / num;const float threshold = 1e-6; if (tep < threshold)return VEC3_ZERO;Vector3 result = Vector3(x * tep , y * tep, z * tep);return result;}Vector3 operator /=(float num) {float tep = 1.0f / num;float tep = 1.0f / num;const float threshold = 1e-6;if (tep < threshold) *this = VEC3_ZERO;else*this *= tep;return *this;}bool operator ==(const Vector3 &vec) const{bool isbool = vec.x == x && vec.y == y && vec.z == z;return isbool;}/** 坐标置0*/void zero() { x = y = z = 0.0f; }/** 取向量模*/float mod() const{if (*this == VEC3_ZERO)return 0;float squaresSum = x * x + y * y + z * z;return sqrt(squaresSum);}/** 归一化,获取单位向量*/Vector3 normal() const { float tep = mod();if (tep == 0)return VEC3_ZERO;return *this/tep;}/** 返回坐标字符串*/std::string string() const {std::stringstream ss;ss << "Vector3:" << "(" << x << ", " << y << ", " << z << ")";return ss.str();}/** 计算与指定坐标的距离*/float distance(const Vector3& vec) const{Vector3 tep = *this - vec;float distance = tep.mod();return distance;}/** 计算与指定坐标的夹角*/float angle(const Vector3& vec) const{float dot = Dot(*this, vec);float mod1 = mod();float mod2 = vec.mod();if (mod1 == 0.0f || mod2 == 0.0f)return 0.0f;float result = acosf(dot / (mod1 + mod2));return result;}/** 计算与指定坐标的方向是否平行*/bool isParallel(const Vector3& vec) {Vector3 result = Cross(*this, vec);return result == VEC3_ZERO;}
};
const Vector3 VEC3_ZERO = Vector3(0, 0, 0);
const Vector3 VEC3_ONE = Vector3(1, 1, 1);
inline Vector3 operator *(float num, const Vector3 &vec) {return vec * num;
}
/*
* 计算两个坐标间的距离
*/
inline float Distance(const Vector3& vec1, const Vector3& vec2) {Vector3 tep = vec1 - vec2;float distance = tep.mod();return distance;
}
/*
* 点乘
*/
inline float Dot(const Vector3& vec1, const Vector3& vec2) {float result = vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z;return result;
}
/*
* 叉乘
*/
inline Vector3 Cross(const Vector3& vec1, const Vector3& vec2) {return Vector3(vec1.y * vec2.z - vec1.z * vec2.y,vec1.z * vec2.x - vec1.x * vec2.z,vec1.x * vec2.y - vec1.y * vec2.x);
}
/*
* 获取两个向量间的夹角
*/
inline float Angle(const Vector3& vec1, const Vector3& vec2) {float dot = Dot(vec1, vec2);float mod1 = vec1.mod();float mod2 = vec2.mod();if (mod1 == 0.0f || mod2 == 0.0f)return 0.0f;float angle = acosf(dot / (mod1 + mod2));return angle;
}
/*
* 两个向量的方向是否平行
*/
inline bool IsParallel(const Vector3& vec1, const Vector3& vec2) {Vector3 result = Cross(vec1, vec2);return result == VEC3_ZERO;
}
#endif // ! __VECTOR3_H_INCLUDED__
```\

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/710426.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

学不动系列-git-hooks和husky+lintstage

git-hooks 为了保证提交的代码符合规范&#xff0c;可以在上传代码时进行校验。常用husky来协助进行代码提交时的eslint校验。husky是基于git-hooks来实现&#xff0c;在使用husky之前&#xff0c;我们先来研究一下git-hooks。 构建git-hooks测试项目 需要使用git-hooks就需…

QPaint绘制自定义仪表盘组件03

网上视频抄的&#xff0c;用来自己看一下&#xff0c;看完就删掉 ui mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QDebug> #include <QtMath> #include <QDialog> #include <QPainter> #include …

网络安全概述(一)

目录 资产保护 资产的类型 资产损失类型 资产保护考虑因素 安全强度、安全代价和侵入可能性的关系 信息安全技术发展 单机系统的信息保密阶段 信息保障阶段 信息保障技术框架IATF PDRR模型 网络攻击类型 阻断攻击、截取攻击、篡改攻击、伪造攻击 被动攻击和主动攻…

C#,双向链表(Doubly Linked List)归并排序(Merge Sort)算法与源代码

1 双向链表 双向链表也叫双链表&#xff0c;是链表的一种&#xff0c;它的每个数据结点中都有两个指针&#xff0c;分别指向直接后继和直接前驱。所以&#xff0c;从双向链表中的任意一个结点开始&#xff0c;都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循…

LNMP架构介绍及配置--部署Discuz社区论坛与wordpress博客

一、LNMP架构定义 1、LNMP定义 LNMP&#xff08;Linux Nginx Mysql Php&#xff09;是指一组通常一起使用来运行动态网站或者服务器的自由软件名称首字母缩写&#xff1b;Linux系统下NginxMySQLPHP这种网站服务器架构。 Linux是一类Unix计算机操作系统的统称&#xff0c;是目…

王者荣耀,急于补齐内容短板

问十个人&#xff0c;有九个人知道《王者荣耀》&#xff1b;但如果再问十个知道《王者荣耀》的人&#xff0c;这款游戏到底讲了一个什么故事&#xff0c;每个角色又有怎样的背景&#xff0c;可能十个人都不知道。 整个新年档口&#xff0c;《王者荣耀》都很忙碌。 1月&#x…

《HelloGitHub》第 95 期

兴趣是最好的老师&#xff0c;HelloGitHub 让你对编程感兴趣&#xff01; 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等&#xff0c;涵盖多种编程语言 Python、Java、Go、C/C、Swift...让你在短时间内…

ODOO12设置收发邮件服务器教程

一、设置-技术 二、设置–技术–发件服务器 信息填写完整后&#xff0c;点击‘测试连接’&#xff0c;若提示成功&#xff0c;则发件服务器设置成功。 三、设置–技术–收件服务器 四、设置–参数–系统参数 修改之前的email系统参数&#xff1a; mail.catchall.alias: 收件服…

Vue页面更新后刷新页面不会渲染解决

小编今天犯了个很低级的错误&#xff0c;导致VUE页面刷新样式不会更新的问题&#xff01; 解决方法&#xff1a;查看你的路由路径大小写是否正确&#xff01;小编是犯了这种错误&#xff0c;特此分享下&#xff01;

ROS 2基础概念#2:节点(Node)| ROS 2学习笔记

ROS 2节点简介 节点是执行计算的进程。节点组合在一起形成一个图&#xff08;graph&#xff09;&#xff0c;并使用主题&#xff08;topic&#xff09;、服务&#xff08;service&#xff09;和参数服务器&#xff08;paramter server&#xff09;相互通信。这些节点旨在以细粒…

进制转换md5绕过 [安洵杯 2019]easy_web1

打开题目 在查看url的时候得到了一串类似编码的东西&#xff0c;源码那里也是一堆base64&#xff0c;但是转换成图片就是网页上我们看见的那个表情包 ?imgTXpVek5UTTFNbVUzTURabE5qYz0&cmd 我们可以先试把前面的img那串解码了 解码的时候发现长度不够&#xff0c;那我们…

博弈论---Nim游戏(公平组合游戏,概念,证明异或为0就是必败态,示例)

目录 概念&#xff1a; 公平组合游戏ICG 有向图游戏 Nim游戏 先手&#xff09;必胜状态 先手&#xff09;必败状态 如何确定先手是否必胜或者必败&#xff08;都采用最优策略&#xff09; 证明&#xff1a;全部异或为0则是必败状态 综上&#xff1a; 例子 概念&#…

babylonjs入门-基础模版+调试GUI

基于babylonjs封装的一些功能和插件 &#xff0c;希望有更多的小伙伴一起玩babylonjs&#xff1b; 欢迎加群&#xff08;点击群号传送&#xff09;&#xff1a;464146715 官方文档 中文文档 案例传送门 ​ 懒得打字&#xff0c;粘贴复制一气呵成

linux系统---LNMP架构下部署Discuz社区论坛与Wordpress博客

目录 一、编译安装Nginx 1、关闭防火墙 2、安装依赖包 3、创建运行用户 4、压缩软件包并编译安装 5、软链接路径优化 ​编辑 6、添加Nginx系统服务 二.编译安装MySQL服务 1.安装依赖环境 ​编辑 2、创建运行用户 3、编译安装 ​编辑 4、修改mysql 配置文件 5、…

HUAWEI 华为交换机 配置基于VLAN的MAC地址学习限制接入用户数量 配置示例

组网需求 如 图 2-15 所示&#xff0c;用户网络 1 通过 LSW1 与 Switch 相连&#xff0c; Switch 的接口为 GE0/0/1 。用户网络2通过 LSW2 与 Switch 相连&#xff0c; Switch 的接口为 GE0/0/2 。 GE0/0/1 、 GE0/0/2 同属于 VLAN2。为控制接入用户数&#xff0c;对 VLAN2 进…

Go语言公开库与私有库及版本控制

公开库与私有库 go mod除了用作模块化开发之外&#xff0c;也是新版本go源码库的私有与共有的重要途径。 module gitee.com/xvwen/gocmd/cwgogengo 1.21.5在go mod中module的名称规定了该源码是否共有&#xff0c;如果该名称与远程git仓库地址一致&#xff0c;则该源码可以通…

如何合理布局子图--确定MATLAB的subplot子图位置参数

确定MATLAB的subplot子图位置参数 目录 确定MATLAB的subplot子图位置参数摘要1. 问题描述2. 计算过程2.1 确定子图的大小和间距2.2 计算合适的figure大小2.3 计算每个子图的position数据 3. MATLAB代码实现3.1 MATLAB代码3.2 绘图结果 4. 总结 摘要 在MATLAB中&#xff0c;使用…

【C++】认识类和对象

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《C》 《Linux》 《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 一、什么是面向对象&#xff1f;二、类的引入三、类的定义四、类的访问限定符与…

HarmonyOS—端云一体化组件

概述 DevEco Studio还为您提供多种端云一体化组件。集成端云一体化组件后&#xff0c;您只需进行简单配置即可向应用用户提供登录、支付等众多功能。 登录组件 您可使用端云一体化登录组件向应用用户提供登录和登出功能&#xff0c;目前支持帐号密码登录、手机验证码登录、以…

【ZooKeeper 】安装和使用,以及java客户端

目录 1. 前言 2. ZooKeeper 安装和使用 2.1. 使用Docker 安装 zookeeper 2.2. 连接 ZooKeeper 服务 2.3. 常用命令演示 2.3.1. 查看常用命令(help 命令) 2.3.2. 创建节点(create 命令) 2.3.3. 更新节点数据内容(set 命令) 2.3.4. 获取节点的数据(get 命令) 2.3.5. 查看…