c++ 空间向量类(Vector3D)的实现
该类可用于描述3D向量和点在空间中的位置。
可以使用该类保存与计算 3D 位置和方向。 此外,它还包含用于执行常见向量操作的函数。
头文件:
#pragma once
#include <cmath>
#include <iostream>
using namespace std;
const double PI = 3.14159265358979323846;
//转角度
double Deg(double rad) { return rad * 180.0 / PI; }
//转弧度
double Rad(double deg) { return deg / 180.0 * PI; }
/*方便进行角度制运算*/
double COS(double angles) { return cos(Rad(angles)); }
double SIN(double angles) { return sin(Rad(angles)); }
double ACOS(double vals) { return Deg(acos(vals)); }
double ASIN(double vals) { return Deg(asin(vals)); }
void Esp(double &val) { if (fabs(val) < 1e-8) val = 0; };
/*3D向量头*/
class Vector3D {public:Vector3D(double px = 1, double py = 0, double pz = 0) :x(px), y(py), z(pz) {};~Vector3D() {};double x, y, z;Vector3D operator = (const Vector3D &b) {this->x = b.x, this->y = b.y, this->z = b.z;return *this;}Vector3D operator + (const Vector3D &b)const { //加法return Vector3D(this->x + b.x, this->y + b.y, this->z + b.z);}Vector3D operator - (const Vector3D &b)const { //减法return Vector3D(this->x - b.x, this->y - b.y, this->z - b.z);}Vector3D operator += (const Vector3D &b) { //加法this->x += b.x, this->y += b.y, this->z += b.z;return Vector3D(this->x + b.x, this->y + b.y, this->z + b.z);}Vector3D operator -= (const Vector3D &b) { //减法this->x -= b.x, this->y -= b.y, this->z -= b.z;return Vector3D(this->x - b.x, this->y - b.y, this->z - b.z);}Vector3D operator () (double px, double py, double pz) {this->x = px, this->y = py, this->z = pz;return *this;}double operator * (const Vector3D &b)const { //向量内积 标量return (this->x * b.x + this->y * b.y + this->z*b.z);}Vector3D operator * (const double &k)const { //向量数乘return Vector3D(this->x * k, this->y * k, this->z * k);}Vector3D operator *= (const double &k) { //向量数乘this->x *= k, this->y *= k, this->z *= k;return *this;}public: //成员函数double norm()const { //向量的模return sqrt(this->x*this->x + this->y*this->y + this->z*this->z);}double norm2()const {//不开根return (this->x*this->x + this->y*this->y + this->z*this->z);}void Normalizing() {//单位化double k = (*this).norm();if (k == 0) return;this->x /= k, this->y /= k, this->z /= k;}void RotateByVector(double angles, Vector3D stdv = Vector3D(0, 0, 1)) {//空间中绕某一向量旋转一定角度stdv.Normalizing();//先将轴向量单位化{//Vector3D t = *this;//x = (stdv.x * stdv.x * (1 - COS(angles)) + COS(angles)) * t.x +// (stdv.y * stdv.x * (1 - COS(angles)) - stdv.z * SIN(angles)) * t.y +// (stdv.z * stdv.x * (1 - COS(angles)) + stdv.y * SIN(angles)) * t.z;//y = (stdv.x * stdv.y * (1 - COS(angles)) + stdv.z * SIN(angles)) * t.x +// (stdv.y * stdv.y * (1 - COS(angles)) + COS(angles)) * t.y +// (stdv.z * stdv.y * (1 - COS(angles)) - stdv.x * SIN(angles)) * t.z;//z = (stdv.x * stdv.z * (1 - COS(angles)) - stdv.y * SIN(angles)) * t.x +// (stdv.y * stdv.z * (1 - COS(angles)) + stdv.x * SIN(angles)) * t.y +// (stdv.z * stdv.z * (1 - COS(angles)) + COS(angles)) * t.z;//Esp(x), Esp(y), Esp(z);//消除部分误差}/*罗德里格公式计算旋转向量*/*this = (*this)*COS(angles) + (stdv*(stdv*(*this))*(1 - COS(angles))) + (Vector3D(y*stdv.z - z*stdv.y, z*stdv.x - x*stdv.z, x*stdv.y - y*stdv.x)*SIN(angles));}
};double Angle(const Vector3D &a, const Vector3D &b) { //两个向量夹角if (a.norm() == 0) return 0;return ACOS(a*b / (a.norm()*b.norm()));
}
Vector3D multiply(const Vector3D &a, const Vector3D &b) {//向量叉乘 矢量(cross)return Vector3D(a.y*b.z - a.z*b.y, a.z*b.x - a.x*b.z, a.x*b.y - a.y*b.x);
}
istream& operator >> (istream &in, Vector3D &a) {in >> a.x >> a.y >> a.z;return in;
}
ostream& operator<<(ostream &out, const Vector3D &a) {out << "(" << a.x << ", " << a.y << ", " << a.z << ")";return out;
}
bool Parallel(const Vector3D &a, const Vector3D &b) {Vector3D t = multiply(a, b);if (t.x == 0 && t.y == 0 && t.z == 0) return true;return false;
}
使用这个向量类再结合绘图可以较为轻松地绘制有立体效果的图形在空间中的旋转。
实例:
#include <iostream>
#include <vector>
#include <conio.h>
#include <graphics.h>
#include <stdlib.h>
#include <Vector3D.h>
using namespace std;
vector<Vector3D> V; //顶点集
void LINE(Vector3D &sp, Vector3D &ep) { //方便画线line(sp.x, sp.y, ep.x, ep.y);
}
void initDrawStyle() {//初始化绘画风格setlinecolor(RGB(120, 150, 255));setlinestyle(PS_SOLID, 4);
}
void initSet() {//初始化点集/*一个棱锥*/{V.push_back({ 500,300,100 });V.push_back({ 400,400,0 });V.push_back({ 400,400,200 });V.push_back({ 600,400,200 });V.push_back({ 600,400,0 });V.push_back({ 500,500,100 });}}
void drawGraph() { //绘图int sz = V.size();while (1) {for (int i = 0; i < sz; i++)V[i].RotateByVector(0.03, Vector3D(1920, 1080, 0));//绕着窗口主对角线旋转BeginBatchDraw();for (int i = 1; i < 5; i++) {LINE(V[0], V[i]);LINE(V[5], V[i]);}LINE(V[1], V[2]);LINE(V[1], V[4]);LINE(V[3], V[4]);LINE(V[2], V[3]);EndBatchDraw();cleardevice();}
}
int main() {initgraph(1920, 1080);initDrawStyle();initSet();drawGraph();_getch();return 0;
}
内容并不完善,有任何问题欢迎提出~
c++ 空间向量类(Vector3D)的实现相关推荐
- [C++][代码库]Vector3空间向量类
本文用C++实现一个简单的Vector3类的功能,暂时有的功能是: 1 + - * /算术运算 2 向量的数量积,又叫:点乘 3 向量的向量积,又叫:叉乘 4 向量单位化(normalization) ...
- 三维向量类Vector类封装,包含三维向量一些基本运算
(1)网上参考的三维向量类 /*--------------------------------------------------* 类名称:三维向量类-Vector.h* 类作用:用于三维空间中向 ...
- 《C++语言基础》实践参考——我的向量类
返回:贺老师课程教学链接 项目要求 [项目4-我的向量类] 建立一个向量类MyVector,声明如下,请完成类的定义 class MyVector //定义向量类 { public:MyVector( ...
- Kinect体感机器人(三)—— 空间向量法计算关节角度
Kinect体感机器人(三)-- 空间向量法计算关节角度 By 马冬亮(凝霜 Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 终于写到体感机器人的核心代码了, ...
- java 三维向量类_三维向量类
还是在读书的时候帮外专业朋友做作业,用GDI实现三维空间的立方体绘制和旋转的操作,那个时候自己根据<线性代数与空间解析几何>以及<计算机图形学>等课程的相关知识写了一个三维向量 ...
- (转)Kinect体感机器人—— 空间向量法计算关节角度
Kinect体感机器人(三)-- 空间向量法计算关节角度 By 马冬亮(凝霜 Loki) 一个人的战争(http://blog.csdn.net/MDL13412) 终于写到体感机器人的核心代码了, ...
- java向量vector类,java数据结构——Vector(向量类)
Vector底层是用数组实现的,其容量是可以动态扩展的,默认初始容量是10,默认增长因子是0,详细的扩容方式会在构造方法中讲述. Vector对象和ArrayList一样可以随意插入不同类的对象,因为 ...
- 《3D数学基础》实践1 向量类代码分析
理解数学,理解代码! 大家好,我是老G! 今天为大家带来<3D数学基础>系列视频. 主要讲解:游戏开发中用到的3D数学知识,包括:定义,定理,推论. 也包括他们的推导过程,以及应用举例. ...
- 【C++进阶】利用重载二元运算符改进平面向量类Vec2D
先前回顾 在[C++进阶] 遵循TDD原则,实现平面向量类(Vec2D)中我们初步实现了Vec2D内容,现在做出一定的改进: 实现Vec2D的一半二元算数运算符重载 1. + - (两个Vec2D对象 ...
最新文章
- 《树莓派开发实战(第2版)》——1.15 使用蓝牙设备
- 百度研究院再升级,迎来9位世界级科学家
- ORACLE学习笔记--性能优化2
- 当顶流厂商谈论智能手表,他们到底在谈论什么
- 『设计模式』难道你现在还不知道:C/S和B/S
- js 中null,undefined区别
- C#开发笔记之06-为什么要尽可能的使用尾递归,编译器会为它做优化吗?
- 广西桂林平均工资是多少?
- matplotlib——折线图
- php array 插值,PHP中的关联数组的插值(双引号字符串)
- 【Pytorch】谈谈我在PyTorch踩过的12坑
- Spring Boot ES 实战,直接拿来用!
- DOCKER基础技术:LINUX NAMESPACE(下)
- 5个高清图片素材网站,免费可商用,不用担心侵权
- U盘数据损坏了不要慌,这两种方法可以轻松找回数据
- android仿小米日历,可周月选择
- linux git版本更新
- Ubuntu中编译linux内核后使用make menuconfig报错的解决办法
- 360全景摄影的逆光问题如何解决?
- 软件工程实践结对作业一