EGE基础:其它相关

EGE专栏:EGE专栏

一、向量计算

  EGE提供了一个用于三维向量计算的 VECTOR3D 类,可以简单地进行向量加减、点乘、叉乘、求向量之间的夹角、求向量长度、向量绕轴旋转等计算操作,相关资料请查阅官方文档。
  下面是 VERTOR3D 类的声明(对比头文件内容有区别,移除了函数具体的定义,只对功能进行说明):

// 三维向量,在右手坐标系下计算

struct VECTOR3D;


void EGEAPI rotate_point3d_x(VECTOR3D  * pt, float r);	//三维坐标 pt 绕 x 轴旋转 r 弧度
void EGEAPI rotate_point3d_y(VECTOR3D  * pt, float r);	//三维坐标 pt 绕 y 轴旋转 r 弧度
void EGEAPI rotate_point3d_z(VECTOR3D  * pt, float r);	//三维坐标 pt 绕 z 轴旋转 r 弧度

//三维向量
struct VECTOR3D {
	float x, y, z;

	//默认构造函数,向量{0, 0, 0}
	VECTOR3D();
	
	//构造函数,向量{x, y, 0}
	VECTOR3D(float _x, float _y);

	//构造函数,向量 {x, y, z}
	VECTOR3D(float _x, float _y, float _z);
	
	// 赋值运算符
	VECTOR3D& operator = (const VECTOR3D& _fp);

	//向量相加
	VECTOR3D& operator += (const VECTOR3D& _fp);
	VECTOR3D  operator +  (const VECTOR3D& _fp) const;
	
	//向量相减
	VECTOR3D& operator -= (const VECTOR3D& _fp);
	VECTOR3D  operator -  (const VECTOR3D& _fp) const;
	
	//向量乘以标量
	VECTOR3D& operator *= (float f); //缩放
	VECTOR3D  operator *  (float f) const; //缩放
	
	//向量点乘
	float operator * (const VECTOR3D& _fp) const; //点乘
	
	//向量叉乘
	VECTOR3D  operator &  (const VECTOR3D& _fp) const;
	VECTOR3D& operator &= (const VECTOR3D& _fp);

	//向量模
	float GetModule() const;
	
	//向量模的平方
	float GetSqrModule() const;

	//转为模长为m的同向向量
	VECTOR3D& SetModule(float m);

	// 绕向量 v {x, y, z} 旋转 rad 弧度
	VECTOR3D& Rotate(float rad, const VECTOR3D& v);
	VECTOR3D& Rotate(float rad, float x, float y, float z);

	绕由s 叉乘 e得到的与 垂直于 s 和 e 的向量旋转,旋转的弧度与 s 旋转至 e 的弧度一致。
	VECTOR3D& Rotate(const VECTOR3D& e, const VECTOR3D& s = VECTOR3D(0.0f, 0.0f, 1.0f));

	//返回 s 与 e 的夹角大小(以弧度为单位)
	static float GetAngel(const VECTOR3D& e, const VECTOR3D& s = VECTOR3D(0.0f, 0.0f, 1.0f));
};

二、随机函数

  C标准库 <stdlib.h> 中已经有了 rand() 来生成随机数,为什么 EGE 中还额外增加生成随机数的函数呢?
  这时因为C标准库中的实现,生成的随机数一般是16位无符号整数,取值范围是 0 ~ 65535,精度稍低,只能满足一般的要求。所以 EGE 增加了可以生成 32位随机整数的函数。

1. 随机数列初始化

  使用前必须先调用下面的函数一次, 否则得到的将是固定的序列。不调用的话一般用来调试,因为都是同一个随机序列,可以用来分析不同的结果。

void randomize();

2. 生成随机数:random()

  调用一次 randomize() 即可确定一个随机数列,后面就可以不断地使用 random(n) 来生成一个 0 0 0 n n n 范围内的随机数(不包含 n n n)。

//生成一个 0 到 n 范围内的随机数
unsigned int random(unsigned int n);

如果参数 n 为0 ,那么随机生成一个32位整数(0 ~ 0xFFFFFFFF)。

3. 生成范围内的随机整数:

  如果是想生成一个 [ m i n , m a x ) \left[ min, max \right) [min,max)范围内的随机值,那么可以先生成 [ 0 , m a x − m i n ) \left[ 0, max - min \right) [0,maxmin) 范围内的随机数,然后将值加上最小值 m i n min min,即可想要的值。
  考虑到 m i n ⩾ m a x min \geqslant max minmax 这种不合法的情况,范围内没有任何元素,但又必须返回一个值,所以可以返回一个原本不可能出现的特殊值 INT_MAX(即 int 类型的最大值)来表示这种无效的情况。这样可以通过返回值是否等于 INT_MAX 来判断参数的有效性。同时,这在参数有效时并不会对结果有影响。

  因为范围 [ m i n , m a x ) \left[ min, max \right) [min,max) 是左闭右开, m a x max max 不包括在内,因此不可能出现 int 的最大值。

  实现如下:

#include <limits.h>

// 返回在[min, max)范围内的一个随机整数。特殊情况:当 min <= max时返回 INT_MAX
int randomValue(int min, int max)
{
	if (min >= max)
		return INT_MAX;
	else
		return random(max - min) + min;
}

  如果是想从 [ m i n , m a x ) \left[ min, max \right) [min,max)范围内一个以 m i n min min 起始,间隔为 d d d 的等差数列中随机取一个值,那么可以先求出这个范围内等差数列元素的个数 num,再使用 random(num) 生成一个 [0, num) 范围内的随机数 r,最后通过公式 r * d + min 就可以对应到的数列中的相应元素。
  实现如下:

// 返回在[min, max)范围内以interval为差的等差序列中的一个随机元素(特殊值:当 min <= max时返回 INT_MAX)
int randomValue(int min, int max, int interval)
{
	//空集,返回无效值 INT_MAX
	if (min >= max)
		return INT_MAX;
	
	//差值为0或负时,范围内的数列只有一个元素min
	if (interval <= 0)
		return min;
		
	//这里利用了向上取整的公式: (x + (d - 1)) / d来处理,求元素个数num
	int num =((max - min) + (interval - 1)) / interval;	
	
	return random(num) * interval  + min;
}

  例如,想要在10~100范围内的偶数(包括10 和 100)中随机取出一个值,那么可以得到等差数列的范围是 [10, 101), 差为 2,按如下调用即可:

randomValue(10, 101, 2);

4. 生成0.0~1.0之间的随机浮点数

  生成 0.0 ~ 1.0 范围内的随机数(0.0取到,1.0取不到)是使用 randomf() 函数,函数声明如下:

double randomf();

  如果想要扩大到另一个范围,可以将随机数乘以这个范围大小,再加上最小值即可。如生成10.0 到 100.0之间的小数(不包括100), 范围大小 = 最大值 - 最小值= 90.0, 最小值min = 10.0,可以得到:

double min = 10.0, max = 100.0;

// 取[min, max)范围内的随机值
double r = randomf() * (max - min) + min;



EGE专栏:EGE专栏

  • 12
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

依稀_yixy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值