Bezier曲線曲面的C++實現

        按照計劃,今天是要寫一篇博客的,可是實在不知道寫啥,而且現在時間比較趕,等下還要準備明天深度學習課題組的報告,所以,就拿出一個上個星期寫的比較挫的關於Bezier曲線曲面的C++基礎類的實現,當然,這還是一個初始版本,所以功能還不齊全,只實現了一些基本的功能,後期可以繼續更新。

        首先,我寫的程序中用到了智能指針數組shared_array,因爲 比較討厭動態指針的手動分配和對應的手動添加代碼delete或者delete[],這個智能指針來自於boost準標準C++模板庫,如果要直接使用代碼的話,還需要配置下這個庫,具體配置可以參考我的博客http://blog.csdn.net/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去做現實,基礎代碼比較多。功能比較簡單,也沒有做什麼異常處理,將就下吧。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章