Bezier曲线曲面的C++实现

本文介绍了一个关于Bezier曲线和曲面的基础C++类实现。该实现使用了智能指针来管理控制点,并提供了计算曲线上点的方法。此外,文章还提供了一个用于三维向量运算的CGMath类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        按照计划,今天是要写一篇博客的,可是实在不知道写啥,而且现在时间比较赶,等下还要准备明天深度学习课题组的报告,所以,就拿出一个上个星期写的比较挫的关于Bezier曲线曲面的C++基础类的实现,当然,这还是一个初始版本,所以功能还不齐全,只实现了一些基本的功能,后期可以继续更新。

        首先,我写的程序中用到了智能指针数组shared_array,因为 比较讨厌动态指针的手动分配和对应的手动添加代码delete或者delete[],这个智能指针来自于boost准标准C++模板库,如果要直接使用代码的话,还需要配置下这个库,具体配置可以参考我的博客http://blog.youkuaiyun.com/chaojiwudixiaofeixia/article/details/49419895(C++智能指针shared_array),有了这个基本环境,下面我就直接上代码了,总共四个文件。

        1. Bezier.h

// ----------------------------------------------------------------------------------------------------------------------------
//
// Version 1.00
//
// ----------------------------------------------------------------------------------------------------------------------------
#pragma once
#include <boost\smart_ptr.hpp>
#include "CGMath.h"
using namespace boost;
class BezierCurve3D {
public:
	shared_array<vec3> cp;
	int degree; // degree of the curves
	BezierCurve3D();
	~BezierCurve3D(); 
	BezierCurve3D(shared_array<vec3> p, int dg);// p,dg分别表示控制点和曲线次数
	void SetCurve(shared_array<vec3> p, int dg);// 类似于构造函数
	vec3 Point(float u);// 用De Casteljau算法计算曲线上的点
};

class BezierSurface3D {
public:
	int udeg, vdeg; // degree of the surface at diffrent directions
	shared_array<vec3> cp; // 控制多边形,按照行扫描的方式构成的控制点,数目应该就是m*n
	BezierSurface3D();
	~BezierSurface3D();
	BezierSurface3D(shared_array<vec3> p, int udg, int vdg);
	void SetSurface(shared_array<vec3> p, int udg, int vdg);
	vec3 Point(float u, float v);
};

         2. Bezier.cpp

#include "Bezier.h"
///////////////////////////////// C U R V E //////////////////////////////////////////
BezierCurve3D::BezierCurve3D()
:degree(0)
{
}

BezierCurve3D::~BezierCurve3D()
{
}

BezierCurve3D::BezierCurve3D(shared_array<vec3> p, int dg)
{
	degree = dg;
	cp = shared_array<vec3>(new vec3[degree + 1]);
	for (int i = 0; i <= degree; i++) {
		cp[i] = p[i];
	}
}

void BezierCurve3D::SetCurve(shared_array<vec3> p, int dg)
{
	degree = dg;
	cp = shared_array<vec3>(new vec3[degree + 1]);
	for (int i = 0; i <= degree; i++) {
		cp[i] = p[i];
	}
}

vec3 BezierCurve3D::Point(float u)
{
	shared_array<vec3> cq(new vec3[degree + 1]);
	for (int i = 0; i <= degree; i++) {
		cq[i] = cp[i];
	}
	for (int k = 1; k <= degree; k++) {
		for (int i = 0; i <= degree - k; i++) {
			cq[i] = (1 - u)*cq[i] + u*cq[i + 1];
		}
	}
	return cq[0];
}

///////////////////////////////// S U R F A C E //////////////////////////////////////////
BezierSurface3D::BezierSurface3D()
{
}

BezierSurface3D::~BezierSurface3D()
{
}

BezierSurface3D::BezierSurface3D(shared_array<vec3> p, int udg, int vdg)
{
	udeg = udg;
	vdeg = vdg;
	int count = (udg + 1)*(vdg + 1);
	cp = shared_array<vec3>(new vec3[count]);
	for (int i = 0; i < count; i++) {
		cp[i] = p[i];
	}
}

void BezierSurface3D::SetSurface(shared_array<vec3> p, int udg, int vdg)
{
	udeg = udg;
	vdeg = vdg;
	int count = (udg + 1)*(vdg + 1);
	cp = shared_array<vec3>(new vec3[count]);
	for (int i = 0; i < count; i++) {
		cp[i] = p[i];
	}
}

vec3 BezierSurface3D::Point(float u,float v)
{
	int count = (udeg + 1)*(vdeg + 1);
	shared_array<vec3> cq(new vec3[count]);
	for (int i = 0; i < count; i++) {
		cq[i] = cp[i];
	}
	for (int j = 0; j <= udeg; j++) {
		for (int k = 1; k <= vdeg; k++) {
			for (int i = 0; i <= vdeg - k; i++) {
				cq[i + j*(vdeg + 1)] = (1 - v)*cq[i + j*(vdeg + 1)] + v*cq[i + 1 + j*(vdeg + 1)];
			}
		}
	}
	for (int k = 1; k <= udeg; k++) {
		for (int i = 0; i <= udeg - k; i++) {
			cq[i*(vdeg + 1)] = (1 - u)*cq[i*(vdeg + 1)] + u*cq[(i + 1)*(vdeg + 1)];
		}
	}
	return cq[0];
}
        其中包含的CGMath头文件和对应的源文件如下,主要是实现三维数据的一些基本运算功能。
        3. CGMath.h
// ----------------------------------------------------------------------------------------------------------------------------
//
// Version 1.00
//
// ----------------------------------------------------------------------------------------------------------------------------

#pragma once

#include <cmath>
// 三维向量,点类
class vec3{
public:
	union{
		struct{ float x, y, z; };
		struct{ float s, t, p; };
		struct{ float r, g, b; };
	};
	vec3() : x(0.0f), y(0.0f), z(0.0f){} // 默认构造函数
	~vec3(){} // 析构
	vec3(float x, float y, float z) : x(x), y(y), z(z){} 
	vec3(const vec3 &u) : x(u.x), y(u.y), z(u.z){}
	// 运算符重载
	vec3& operator = (const vec3 &u){ x = u.x; y = u.y; z = u.z; return *this; } 
	vec3 operator - (){ return vec3(-x, -y, -z); }
	float* operator & (){ return (float*)this; }
	vec3& operator += (float num){ x += num; y += num; z += num; return *this; }
	vec3& operator += (const vec3 &u){ x += u.x; y += u.y; z += u.z; return *this; }
	vec3& operator -= (float num){ x -= num; y -= num; z -= num; return *this; }
	vec3& operator -= (const vec3 &u){ x -= u.x; y -= u.y; z -= u.z; return *this; }
	vec3& operator *= (float num){ x *= num; y *= num; z *= num; return *this; }
	vec3& operator *= (const vec3 &u){ x *= u.x; y *= u.y; z *= u.z; return *this; }
	vec3& operator /= (float num){ x /= num; y /= num; z /= num; return *this; }
	vec3& operator /= (const vec3 &u){ x /= u.x; y /= u.y; z /= u.z; return *this; }
	friend vec3 operator + (const vec3 &u, float num){ return vec3(u.x + num, u.y + num, u.z + num); }
	friend vec3 operator + (float num, const vec3 &u){ return vec3(num + u.x, num + u.y, num + u.z); }
	friend vec3 operator + (const vec3 &u, const vec3 &v){ return vec3(u.x + v.x, u.y + v.y, u.z + v.z); }
	friend vec3 operator - (const vec3 &u, float num){ return vec3(u.x - num, u.y - num, u.z - num); }
	friend vec3 operator - (float num, const vec3 &u){ return vec3(num - u.x, num - u.y, num - u.z); }
	friend vec3 operator - (const vec3 &u, const vec3 &v){ return vec3(u.x - v.x, u.y - v.y, u.z - v.z); }
	friend vec3 operator * (const vec3 &u, float num){ return vec3(u.x * num, u.y * num, u.z * num); }
	friend vec3 operator * (float num, const vec3 &u){ return vec3(num * u.x, num * u.y, num * u.z); }
	friend vec3 operator * (const vec3 &u, const vec3 &v){ return vec3(u.x * v.x, u.y * v.y, u.z * v.z); }
	friend vec3 operator / (const vec3 &u, float num){ return vec3(u.x / num, u.y / num, u.z / num); }
	friend vec3 operator / (float num, const vec3 &u){ return vec3(num / u.x, num / u.y, num / u.z); }
	friend vec3 operator / (const vec3 &u, const vec3 &v){ return vec3(u.x / v.x, u.y / v.y, u.z / v.z); }
};

// ----------------------------------------------------------------------------------------------------------------------------

vec3 cross(const vec3 &u, const vec3 &v); // 
float dot(const vec3 &u, const vec3 &v);
float length(const vec3 &u);
float length2(const vec3 &u);
vec3 normalize(const vec3 &u);

// ----------------------------------------------------------------------------------------------------------------------------

        4. CGMath.cpp

#include "CGMath.h"





// ----------------------------------------------------------------------------------------------------------------------------

vec3 cross(const vec3 &u, const vec3 &v)
{
	return vec3(u.y * v.z - u.z * v.y, u.z * v.x - u.x * v.z, u.x * v.y - u.y * v.x);
}

float dot(const vec3 &u, const vec3 &v)
{
	return u.x * v.x + u.y * v.y + u.z * v.z;
}

float length(const vec3 &u)
{
	return sqrt(u.x * u.x + u.y * u.y + u.z * u.z);
}

float length2(const vec3 &u)
{
	return u.x * u.x + u.y * u.y + u.z * u.z;
}

vec3 normalize(const vec3 &u)
{
	return u / sqrt(u.x * u.x + u.y * u.y + u.z * u.z);
}
        至于怎么使用,我就不加代码了,因为还涉及到用OpenGL去做现实,基础代码比较多。功能比较简单,也没有做什么异常处理,将就下吧。。。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值