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.mfbz.cn/a/419093.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL学习Day24—数据库的设计规范

一、数据库设计的重要性: 1.糟糕的数据库设计产生的问题: (1)数据冗余、信息重复、存储空间浪费 (2)数据更新、插入、删除的异常 (3)无法正确表示信息 (4)丢失有效信息 (5)程序性能差 2.良好的数据库设计有以下优点: (1)节省数据的存储空间 (2)能够保证数据的完整性 …

matlab:涉及复杂函数图像的交点求解

matlab&#xff1a;涉及复杂函数图像的交点求解 在MATLAB中求解两个图像的交点是一个常见的需求。本文将通过一个示例&#xff0c;展示如何求解两个图像的交点&#xff0c;并提供相应的MATLAB代码。 画出图像 首先&#xff0c;我们需要绘制两个图像&#xff0c;以便直观地看…

模拟算法题练习(二)(DNA序列修正、无尽的石头)

&#xff08;一、DNA序列修正&#xff09; 问题描述 在生物学中&#xff0c;DNA序列的相似性常被用来研究物种间的亲缘关系。现在我们有两条 DNA序列&#xff0c;每条序列由 A、C、G、T 四种字符组成&#xff0c;长度相同。但是现在我们记录的 DNA序列存在错误&#xff0c;为了…

Elasticsearch入门-环境安装ES和Kibana以及ES-Head可视化插件和浏览器插件es-client

Elasticsearch入门-环境安装ES和Kibana 安装 ES Windows安装ESHead安装浏览器插件 es-clientKibana 安装 安装es,安装header 安装kibana&#xff0c;安装多种分词器ik… 安装 ES Windows安装 ① 下载压缩包并解压官网链接&#xff1a;https://www.elastic.co/cn/downloads/ela…

【MATLAB】兔子机器人腿部_simulink模型解读(及simulink中的simscape的各模块介绍)

一、动力学模型 总系统引脚含义 关节电机 Fcn 搭建方程&#xff0c;输入与输入方程 phi1 -q 大腿 小腿同理 车轮 另一边对称 虚拟腿传感器 二、控制模型 VMC解算五连杆 Pulse Generator 腿长控制器PID leg_conv.m&#xff1a;可由虚拟腿目标扭矩和推力求得电机所需…

通过jenkins进行部署java程序到centos上

1.通过jumpserver访问到centos上&#xff0c;准备下java环境 // step1: 先编辑下 vim /etc/profile// step2: 编写好环境变量 JAVA_HOME/usr/local/java export JAVA_HOME export ZOOKEEPER_HOME/opt/zookeeper/apache-zookeeper-3.7.0-bin PATH$PATH:$JAVA_HOME/bin:$ZOOKEEP…

正信晟锦:借了钱的人一直不接电话不回信息咋办

在金钱往来中&#xff0c;遇到借出的钱款无法按时回收&#xff0c;且借款人如同人间蒸发一般不接电话、不回信息&#xff0c;确实让人焦虑。面对这种情形&#xff0c;我们需采取明智而有效的措施&#xff0c;以保护自身的权益。 首要策略是保持冷静&#xff0c;不要让情绪主导行…

民间最大的天涯社区宣布:今起,全面恢复!

想到去年一则不起眼的消息&#xff1a;天涯社区已经无法打开。 时代抛弃你的时候&#xff0c;都不说一声再见&#xff0c;现实就是这样残酷。 在互联网的浩瀚星河中&#xff0c;天涯社区曾是最亮的那颗星星&#xff0c;见证了无数网友的青春岁月。 记得我读大学的时候&#xff…

npm使用国内淘宝镜像的方法整理

命令配置安装&#xff1a; 淘宝镜像&#xff1a; npm config set registry https://registry.npm.taobao.org/ 官方镜像&#xff1a; npm config set registry https://registry.npmjs.org 通过cnpm安装&#xff1a; npm install -g cnpm --registryhttps://registry.npm.…

基于springboot+vue的科研工作量管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

航拍无人机技术,航拍无人机方案详解,无人机摄影技术

航拍无人机是利用遥控技术和摄像设备&#xff0c;在空中进行拍摄和录像的无人机。这种无人机通常具有高清摄像设备、图像传输设备、GPS定位系统、智能控制系统等&#xff0c;可以轻松实现各种拍摄角度和高度&#xff0c;广泛应用于影视制作、旅游景区航拍、城市规划、环保监测等…

111.龙芯2k1000-pmon(11)- gzrom-dtb.bin 文件的组成

最近又要折腾2k1000的设备了&#xff0c;研究了一下gzrom文件组成部分。 pmon的编译可以参考之前的文档&#xff0c;这里我就不详述了 源码&#xff1a;GitHub - zhaozhi0810/pmon-ls2k1000-2022 gzrom-dtb.bin的生成命令在Makefile.inc&#xff08;zloader.ls2k-hj20004目录…

Vue+SpringBoot打造农村物流配送系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统登录、注册界面2.2 系统功能2.2.1 快递信息管理&#xff1a;2.2.2 位置信息管理&#xff1a;2.2.3 配送人员分配&#xff1a;2.2.4 路线规划&#xff1a;2.2.5 个人中心&#xff1a;2.2.6 退换快递处理&#xff1a;…

冒泡、插入、希尔、选择、堆排序、快速排序(附源码)

目录 插入排序&#xff1a; 核心思想&#xff1a; 时间复杂度&#xff1a; 冒泡排序&#xff1a; 核心思想&#xff1a; 时间复杂度&#xff1a; 希尔排序&#xff1a; 核心思想&#xff1a; 时间复杂度&#xff1a; 选择排序&#xff1a; 核心思想&#xff1a; 时间…

YOLO目标检测——斑马线目标检测数据集【含对应voc、coco和yolo三种格式标签】

实际项目应用&#xff1a;自动驾驶系统、智能交通监控、行人保护系统、辅助驾驶功能数据集说明&#xff1a;真实场景的高质量图片数据&#xff0c;数据场景丰富标签说明&#xff1a;使用lableimg标注软件标注&#xff0c;标注框质量高&#xff0c;含voc(xml)、coco(json)和yolo…

NVIDIA\CUDA\cudnn安装以及visual studio2022编译安装ceres2.2.0库

一、NVIDIA驱动安装 网址:官方驱动 | NVIDIA 因为本文之后需要visual studio2022进行编译&#xff0c;所以在安装NVIDIA\CUDA\cudnn之前你先得安装visual studio2022 点击NVIDIA控制面板&#xff0c;NVIDIA Control Panel 查看产品家族 根据产品家族选择驱动&#xff0c;点…

【QT 5 +Linux下软件qt软件打包+qt生成软件创建可以安装压缩包+学习他人文章+第三篇:学习打包】

【QT 5 Linux下软件qt软件打包qt生成软件创建可以安装压缩包学习他人文章第三篇&#xff1a;学习打包】 1、前言2、实验环境3、自我学习总结-本篇总结&#xff08;1&#xff09;了解安装包的目录结构&#xff08;2&#xff09;了解要编写文件与编写脚本1. control文件2. postin…

一封来自 DatenLord 关于GSoC 2024的挑战书

Google Summer of Code 是一项全球性的在线计划&#xff0c;致力于将新的contributor引入开源软件开发领域。GSoC 参与者在导师的指导下&#xff0c;与开源组织合作开展为期 12 周以上的编程项目。今年&#xff0c;达坦科技入选作为开源社区组织&#xff0c;携CNCF Sandbox项目…

比亚迪领航新能源时代:汉唐传承,品牌力量

比亚迪&#xff0c;以中国文化的深度与自信&#xff0c;为新能源汽车领域注入强大动力。汉唐车型&#xff0c;不仅承载着中国古代文明的辉煌&#xff0c;更以其创新技术和环保理念&#xff0c;终结油电之争&#xff0c;让燃油车再次破防。作为销量冠军&#xff0c;比亚迪品牌的…

中间件-Nginx加固(控制超时时间限制客户端下载速度并发连接数)

中间件-Nginx加固&#xff08;控制超时时间&限制客户端下载速度&并发连接数&#xff09; 1.1 Nginx 控制超时时间配置1.2 Nginx 限制客户端下载速度&并发连接数 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 1.1 Nginx 控制超…
最新文章