X
xu_orient
Unregistered / Unconfirmed
GUEST, unregistred user!
求助:因为可用积分只有50几分了,所以只好好请各位海涵啦!
//根据模型数据,用OpenGL画图。该模型是一个两头细,中间粗的柱状转炉,提供的数据是
//子午面直角坐标系下的值,需要转化到空间直角坐标系下去。
//采用画Bezier曲面的库函数来画图,画出的图形总是有许多"转折点",而不是一个光滑的炉
//子形状,而且,我很想让图形经过每一个控制点,以便于以后根据控制点做图形交互。
//这在Bezier曲面方式下不知道是不是注定行不通。试着用Nurbs曲面方式,却发现给出的
//PGLUnurbs型的变量编译时Delphi 5根本不认识它,而库GLU中明明又是定义了该类型的。
//另外,炉子本来是有底的,该代码没有包含画炉子的底,不知道如何画出。
//画出的图形转动时有重影,不知如何消除它。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,ExtCtrls,Menus,GL,GLU,cgLight,cgWindow,Glut,cgTypes;
type
TGLfloat3v =
array[0..2] of GLfloat;
TInteger3v =
array[0..2] of Integer;
TForm1 = class(TCGForm)
Timer1: TTimer;
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
procedure StarvePot(Grid : GLint; Scale : GLdouble; ShadeType : GLenum);
{ Public declarations }
end;
var
Form1: TForm1;
L:TcgLight;
patchwithin,patchOut: Array[0..349,0..2] of GLfloat; //内壁和外壁控制点,各350个
ax:integer=0; //绕x轴的旋转变量
ay:integer=0; //绕Y轴的旋转变量
m:Tpoint; //鼠标位置
Scale:single=1; //缩放比例的系数
const
MaxNumber:GLInt=350; //控制点的数目
StarveTex : //定义纹理
Array[0..1, 0..1, 0..1] of GLfloat =
( ((0, 0), (1, 0)),
((0, 1), (1, 1)) );
pi:
GLfloat=3.14159265;
StarveData : //给出了350个控制点,该转炉是一个旋转体,转炉的控制点是
//子午面直角坐标下的数据,所谓子午面直角坐标系,就是用母线和轴组成的平面
//将旋转体剖成多个小块,小块从-180度到+180度,类似于沿经线划分地球,每一小块
//以母线和旋转轴组成的面为X-Y平面直角坐标系,原点取旋转轴上深度为0的点。
//此处将转炉从-180到+180分成24份,控制点P(L,x,y1,y2):L代表该点的度数,
//x代表深度,y1代表该点所在的圆弧半径,y2代表该点的壁厚。炉子是有厚度的,
//当炉子竖直放置时,P1(L,x,y1)定义了炉子内壁上P1点的位置,而Q1(L,x,y1+y2)则
//定义了与P1点对应的炉子外壁Q1点的位置。
//在将子午面直角坐标系上的控制点P(L,x,y1,y2)转化到空间直角坐标系下的内壁控制点P1(X1,Y1,Z1)
//和外壁控制点Q1(X2,Y2,Z2)时,对P1点,有:X1=y1×cos(L),Y1=y1*sin(L),Z1=x;
//对于Q1,有: X2=(y1+y2)*cos(L),Y2=(y1+y2)*sin(L),Z2=x.
Array[0..349, 0..3] of GLfloat =
( ( -180, -2.0, 2.0, 0.7), // 1
( -165, -2.0, 2.0, 0.7), //四个值依次代表度数,深度,内壁半径,壁厚
( -150, -2.0, 2.0, 0.7), //每相同深度取25个点,实际上第1点和第25点是重合的,
//为简便计,将同一深度内壁半径
( -135, -2.0, 2.0, 0.7), //和壁厚设成相同的 .
( -120, -2.0, 2.0, 0.7), //在用Bezier库函数画图时,取的4×4控制点是按
( -105, -2.0, 2.0, 0.7), //每相同深度各取4个,各控制块的度数要对应,深度上依次推进的。
( -90, -2.0, 2.0, 0.7), //相同深度的12块4*4控制块组成一个封闭的环面,在深度上推进6次,
//共有6*12个控制块来组成转炉的内壁面,外壁面也是6×12个控制块。
( -75, -2.0, 2.0, 0.7),
//如第1个内壁面控制块从StarveData的第1,2,3,4,26,27,28,29,51,52,52,54, 76,77,78,79控制点取数,
(-60, -2.0, 2.0, 0.7),
( -45, -2.0, 2.0, 0.7), //第2个块从第3,4,5,6,28,29,30,31,53,54,55,56,78,79,80,81取数。。。,
(-30, -2.0, 2.0, 0.7),// 第11个块从第21,22,23,24,46,47,48,49,71,72,73,74,96,97,98,99取数,
( -15, -2.0, 2.0, 0.7), //特别的,第12块从23,24,25,2,48,49,50,27,73,74,75,52,98,99,100,77取数。。。
( 0, -2.0, 2.0, 0.7), //深度推进后的第13块从51,52,53,54,76,77,78,79,101,102,103,104,126,127,128,129取数
( 15, -2.0, 2.0, 0.7),
( 30, -2.0, 2.0, 0.7),
( 45, -2.0, 2.0, 0.7),
( 60, -2.0, 2.0, 0.7),
( 75, -2.0, 2.0, 0.7),
( 90, -2.0, 2.0, 0.7),
( 105, -2.0, 2.0, 0.7),
( 120, -2.0, 2.0, 0.7),
( 135, -2.0, 2.0, 0.7),
( 150, -2.0, 2.0, 0.7),
( 165, -2.0, 2.0, 0.7),
( 180, -2.0, 2.0, 0.7),
( -180, -1.0, 2.5, 0.7), //26
( -165, -1.0, 2.5, 0.7),
( -150, -1.0, 2.5, 0.7),
( -135, -1.0, 2.5, 0.7),
( -120, -1.0, 2.5, 0.7),
( -105, -1.0, 2.5, 0.7),
( -90, -1.0, 2.5, 0.7),
( -75, -1.0, 2.5, 0.7),
( -60, -1.0, 2.5, 0.7),
( -45, -1.0, 2.5, 0.7),
( -30, -1.0, 2.5, 0.7),
( -15, -1.0, 2.5, 0.7),
( 0, -1.0, 2.5, 0.7),
( 15, -1.0, 2.5, 0.7),
( 30, -1.0, 2.5, 0.7),
( 45, -1.0, 2.5, 0.7),
( 60, -1.0, 2.5, 0.7),
( 75, -1.0, 2.5, 0.7),
( 90, -1.0, 2.5, 0.7),
( 105, -1.0, 2.5, 0.7),
( 120, -1.0, 2.5, 0.7),
( 135, -1.0, 2.5, 0.7),
( 150, -1.0, 2.5, 0.7),
( 165, -1.0, 2.5, 0.7),
( 180, -1.0, 2.5, 0.7),
( -180, 0, 3.0, 0.7), // 51
( -165, 0, 3.0, 0.7),
( -150, 0, 3.0, 0.7),
( -135, 0, 3.0, 0.7),
( -120, 0, 3.0, 0.7),
( -105, 0, 3.0, 0.7),
( -90, 0, 3.0, 0.7),
( -75, 0, 3.0, 0.7),
( -60, 0, 3.0, 0.7),
( -45, 0, 3.0, 0.7),
( -30, 0, 3.0, 0.7),
( -15, 0, 3.0, 0.7),
( 0, 0, 3.0, 0.7),
( 15, 0, 3.0, 0.7),
( 30, 0, 3.0, 0.7),
( 45, 0, 3.0, 0.7),
( 60, 0, 3.0, 0.7),
( 75, 0, 3.0, 0.7),
( 90, 0, 3.0, 0.7),
( 105, 0, 3.0, 0.7),
( 120, 0, 3.0, 0.7),
( 135, 0, 3.0, 0.7),
( 150, 0, 3.0, 0.7),
( 165, 0, 3.0, 0.7),
( 180, 0, 3.0, 0.7),
( -180, 1, 3.2, 0.7), // 76
( -165, 1, 3.2, 0.7),
( -150, 1, 3.2, 0.7),
( -135, 1, 3.2, 0.7),
( -120, 1, 3.2, 0.7),
( -105, 1, 3.2, 0.7),
( -90, 1, 3.2, 0.7),
( -75, 1, 3.2, 0.7),
( -60, 1, 3.2, 0.7),
( -45, 1, 3.2, 0.7),
( -30, 1, 3.2, 0.7),
( -15, 1, 3.2, 0.7),
( 0, 1, 3.2, 0.7),
( 15, 1, 3.2, 0.7),
( 30, 1, 3.2, 0.7),
( 45, 1, 3.2, 0.7),
( 60, 1, 3.2, 0.7),
( 75, 1, 3.2, 0.7),
( 90, 1, 3.2, 0.7),
( 105, 1, 3.2, 0.7),
( 120, 1, 3.2, 0.7),
( 135, 1, 3.2, 0.7),
( 150, 1, 3.2, 0.7),
( 165, 1, 3.2, 0.7),
( 180, 1, 3.2, 0.7),
( -180, 1.5, 3.4, 0.7), //101
( -165, 1.5, 3.4, 0.7),
( -150, 1.5, 3.4, 0.7),
( -135, 1.5, 3.4, 0.7),
( -120, 1.5, 3.4, 0.7),
( -105, 1.5, 3.4, 0.7),
( -90, 1.5, 3.4, 0.7),
( -75, 1.5, 3.4, 0.7),
( -60, 1.5, 3.4, 0.7),
( -45, 1.5, 3.4, 0.7),
( -30, 1.5, 3.4, 0.7),
( -15, 1.5, 3.4, 0.7),
( 0, 1.5, 3.4, 0.7),
( 15, 1.5, 3.4, 0.7),
( 30, 1.5, 3.4, 0.7),
( 45, 1.5, 3.4, 0.7),
( 60, 1.5, 3.4, 0.7),
( 75, 1.5, 3.4, 0.7),
( 90, 1.5, 3.4, 0.7),
( 105, 1.5, 3.4, 0.7),
( 120, 1.5, 3.4, 0.7),
( 135, 1.5, 3.4, 0.7),
( 150, 1.5, 3.4, 0.7),
( 165, 1.5, 3.4, 0.7),
( 180, 1.5, 3.4, 0.7),
( -180, 2.0, 3.4, 0.7), //126
( -165, 2.0, 3.4, 0.7),
( -150, 2.0, 3.4, 0.7),
( -135, 2.0, 3.4, 0.7),
( -120, 2.0, 3.4, 0.7),
( -105, 2.0, 3.4, 0.7),
( -90, 2.0, 3.4, 0.7),
( -75, 2.0, 3.4, 0.7),
( -60, 2.0, 3.4, 0.7),
( -45, 2.0, 3.4, 0.7),
( -30, 2.0, 3.4, 0.7),
( -15, 2.0, 3.4, 0.7),
( 0, 2.0, 3.4, 0.7),
( 15, 2.0, 3.4, 0.7),
( 30, 2.0, 3.4, 0.7),
( 45, 2.0, 3.4, 0.7),
( 60, 2.0, 3.4, 0.7),
( 75, 2.0, 3.4, 0.7),
( 90, 2.0, 3.4, 0.7),
( 105, 2.0, 3.4, 0.7),
( 120, 2.0, 3.4, 0.7),
( 135, 2.0, 3.4, 0.7),
( 150, 2.0, 3.4, 0.7),
( 165, 2.0, 3.4, 0.7),
( 180, 2.0, 3.4, 0.7),
( -180, 2.5, 3.4, 0.7), //151
( -165, 2.5, 3.4, 0.7),
( -150, 2.5, 3.4, 0.7),
( -135, 2.5, 3.4, 0.7),
( -120, 2.5, 3.4, 0.7),
( -105, 2.5, 3.4, 0.7),
( -90, 2.5, 3.4, 0.7),
( -75, 2.5, 3.4, 0.7),
( -60, 2.5, 3.4, 0.7),
( -45, 2.5, 3.4, 0.7),
( -30, 2.5, 3.4, 0.7),
( -15, 2.5, 3.4, 0.7),
( 0, 2.5, 3.4, 0.7),
( 15, 2.5, 3.4, 0.7),
( 30, 2.5, 3.4, 0.7),
( 45, 2.5, 3.4, 0.7),
( 60, 2.5, 3.4, 0.7),
( 75, 2.5, 3.4, 0.7),
( 90, 2.5, 3.4, 0.7),
( 105, 2.5, 3.4, 0.7),
( 120, 2.5, 3.4, 0.7),
( 135, 2.5, 3.4, 0.7),
( 150, 2.5, 3.4, 0.7),
( 165, 2.5, 3.4, 0.7),
( 180, 2.5, 3.4, 0.7),
( -180, 5.5, 3.4, 0.7), //176
( -165, 5.5, 3.4, 0.7),
( -150, 5.5, 3.4, 0.7),
( -135, 5.5, 3.4, 0.7),
( -120, 5.5, 3.4, 0.7),
( -105, 5.5, 3.4, 0.7),
( -90, 5.5, 3.4, 0.7),
( -75, 5.5, 3.4, 0.7),
( -60, 5.5, 3.4, 0.7),
( -45, 5.5, 3.4, 0.7),
( -30, 5.5, 3.4, 0.7),
( -15, 5.5, 3.4, 0.7),
( 0, 5.5, 3.4, 0.7),
( 15, 5.5, 3.4, 0.7),
( 30, 5.5, 3.4, 0.7),
( 45, 5.5, 3.4, 0.7),
( 60, 5.5, 3.4, 0.7),
( 75, 5.5, 3.4, 0.7),
( 90, 5.5, 3.4, 0.7),
( 105, 5.5, 3.4, 0.7),
( 120, 5.5, 3.4, 0.7),
( 135, 5.5, 3.4, 0.7),
( 150, 5.5, 3.4, 0.7),
( 165, 5.5, 3.4, 0.7),
( 180, 5.5, 3.4, 0.7),
( -180, 6.5, 3.3, 0.7), //201
( -165, 6.5, 3.3, 0.7),
( -150, 6.5, 3.3, 0.7),
( -135, 6.5, 3.3, 0.7),
( -120, 6.5, 3.3, 0.7),
( -105, 6.5, 3.3, 0.7),
( -90, 6.5, 3.3, 0.7),
( -75, 6.5, 3.3, 0.7),
( -60, 6.5, 3.3, 0.7),
( -45, 6.5, 3.3, 0.7),
( -30, 6.5, 3.3, 0.7),
( -15, 6.5, 3.3, 0.7),
( 0, 6.5, 3.3, 0.7),
( 15, 6.5, 3.3, 0.7),
( 30, 6.5, 3.3, 0.7),
( 45, 6.5, 3.3, 0.7),
( 60, 6.5, 3.3, 0.7),
( 75, 6.5, 3.3, 0.7),
( 90, 6.5, 3.3, 0.7),
( 105, 6.5, 3.3, 0.7),
( 120, 6.5, 3.3, 0.7),
( 135, 6.5, 3.3, 0.7),
( 150, 6.5, 3.3, 0.7),
( 165, 6.5, 3.3, 0.7),
( 180, 6.5, 3.3, 0.7),
( -180, 6.5, 3.3, 0.7), //226
( -165, 6.5, 3.3, 0.7),
( -150, 6.5, 3.3, 0.7),
( -135, 6.5, 3.3, 0.7),
( -120, 6.5, 3.3, 0.7),
( -105, 6.5, 3.3, 0.7),
( -90, 6.5, 3.3, 0.7),
( -75, 6.5, 3.3, 0.7),
( -60, 6.5, 3.3, 0.7),
( -45, 6.5, 3.3, 0.7),
( -30, 6.5, 3.3, 0.7),
( -15, 6.5, 3.3, 0.7),
( 0, 6.5, 3.3, 0.7),
( 15, 6.5, 3.3, 0.7),
( 30, 6.5, 3.3, 0.7),
( 45, 6.5, 3.3, 0.7),
( 60, 6.5, 3.3, 0.7),
( 75, 6.5, 3.3, 0.7),
( 90, 6.5, 3.3, 0.7),
( 105, 6.5, 3.3, 0.7),
( 120, 6.5, 3.3, 0.7),
( 135, 6.5, 3.3, 0.7),
( 150, 6.5, 3.3, 0.7),
( 165, 6.5, 3.3, 0.7),
( 180, 6.5, 3.3, 0.7),
( -180, 7.0, 3.0, 0.7), //251
( -165, 7.0, 3.0, 0.7),
( -150, 7.0, 3.0, 0.7),
( -135, 7.0, 3.0, 0.7),
( -120, 7.0, 3.0, 0.7),
( -105, 7.0, 3.0, 0.7),
( -90, 7.0, 3.0, 0.7),
( -75, 7.0, 3.0, 0.7),
( -60, 7.0, 3.0, 0.7),
( -45, 7.0, 3.0, 0.7),
( -30, 7.0, 3.0, 0.7),
( -15, 7.0, 3.0, 0.7),
( 0, 7.0, 3.0, 0.7),
( 15, 7.0, 3.0, 0.7),
( 30, 7.0, 3.0, 0.7),
( 45, 7.0, 3.0, 0.7),
( 60, 7.0, 3.0, 0.7),
( 75, 7.0, 3.0, 0.7),
( 90, 7.0, 3.0, 0.7),
( 105, 7.0, 3.0, 0.7),
( 120, 7.0, 3.0, 0.7),
( 135, 7.0, 3.0, 0.7),
( 150, 7.0, 3.0, 0.7),
( 165, 7.0, 3.0, 0.7),
( 180, 7.0 , 3.0, 0.7),
( -180, 7.5, 3.0, 0.7), //276
( -165, 7.5, 3.0, 0.7),
( -150, 7.5, 3.0, 0.7),
( -135, 7.5, 3.0, 0.7),
( -120, 7.5, 3.0, 0.7),
( -105, 7.5, 3.0, 0.7),
( -90, 7.5, 3.0, 0.7),
( -75, 7.5, 3.0, 0.7),
( -60, 7.5, 3.0, 0.7),
( -45, 7.5, 3.0, 0.7),
( -30, 7.5, 3.0, 0.7),
( -15, 7.5, 3.0, 0.7),
( 0, 7.5, 3.0, 0.7),
( 15, 7.5, 3.0, 0.7),
( 30, 7.5, 3.0, 0.7),
( 45, 7.5, 3.0, 0.7),
( 60, 7.5, 3.0, 0.7),
( 75, 7.5, 3.0, 0.7),
( 90, 7.5, 3.0, 0.7),
( 105, 7.5, 3.0, 0.7),
( 120, 7.5, 3.0, 0.7),
( 135, 7.5, 3.0, 0.7),
( 150, 7.5, 3.0, 0.7),
( 165, 7.5, 3.0, 0.7),
( 180, 7.5, 3.0, 0.7),
( -180, 8.0, 2.8, 0.7), //301
( -165, 8.0, 2.8, 0.7),
( -150, 8.0, 2.8, 0.7),
( -135, 8.0, 2.8, 0.7),
( -120, 8.0, 2.8, 0.7),
( -105, 8.0, 2.8, 0.7),
( -90, 8.0, 2.8, 0.7),
( -75, 8.0, 2.8, 0.7),
( -60, 8.0, 2.8, 0.7),
( -45, 8.0, 2.8, 0.7),
( -30, 8.0, 2.8, 0.7),
( -15, 8.0, 2.8, 0.7),
( 0, 8.0, 2.8, 0.7),
( 15, 8.0, 2.8, 0.7),
( 30, 8.0, 2.8, 0.7),
( 45, 8.0, 2.8, 0.7),
( 60, 8.0, 2.8, 0.7),
( 75, 8.0, 2.8, 0.7),
( 90, 8.0, 2.8, 0.7),
( 105, 8.0, 2.8, 0.7),
( 120, 8.0, 2.8, 0.7),
( 135, 8.0, 2.8, 0.7),
( 150, 8.0, 2.8, 0.7),
( 165, 8.0, 2.8, 0.7),
( 180, 8.0, 2.8, 0.7),
( -180, 8.5, 2.8, 0.7), //326
( -165, 8.5, 2.8, 0.7),
( -150, 8.5, 2.8, 0.7),
( -135, 8.5, 2.8, 0.7),
( -120, 8.5, 2.8, 0.7),
( -105, 8.5, 2.8, 0.7),
( -90, 8.5, 2.8, 0.7),
( -75, 8.5, 2.8, 0.7),
( -60, 8.5, 2.8, 0.7),
( -45, 8.5, 2.8, 0.7),
( -30, 8.5, 2.8, 0.7),
( -15, 8.5, 2.8, 0.7),
( 0, 8.5, 2.8, 0.7),
( 15, 8.5, 2.8, 0.7),
( 30, 8.5, 2.8, 0.7),
( 45, 8.5, 2.8, 0.7),
( 50, 8.5, 2.8, 0.7),
( 75, 8.5, 2.8, 0.7),
( 90, 8.5, 2.8, 0.7),
( 105, 8.5, 2.8, 0.7),
( 120, 8.5, 2.8, 0.7),
( 135, 8.5, 2.8, 0.7),
( 150, 8.5, 2.8, 0.7),
( 165, 8.5, 2.8, 0.7),
( 180, 8.5, 2.8, 0.7) //350
);
implementation
{$R *.DFM}
procedure TForm1.StarvePot(Grid : GLint; Scale : GLdouble; ShadeType : GLenum);
//由于用bezier曲面画图时,前一个4×4控制块和后一个在衔接时很难满足C1连续,出现了
//一系列的”不能“,不能画出光滑的图形,而且图形不经过大多数控制点。我试着用Nurbs
//曲面方式的GLuNurbsSurface库函数来画,结果定义的PGLUnurbs对象编译都通不过。不知道
//是抱定bezier法到底,还是用Nurbs法或者其他别的方法更合适。
var
P1, Q1 : Array[0..3, 0..3, 0..2] of GLfloat;
N,I, J, K, L : GLInt;
begin { Teapot }
//首先将数据化至空间直角坐标系下
for I:=0 to MaxNumber-1 do
begin
//直角坐标系下的内壁数据
PatchWithin[I,0]:=StarveData[I,2]*cos(pi*StarveData[I,0]/180); //X=y1*cos(L)
patchWithin[I,1]:=StarveData[I,2]*sin(pi*StarveData[I,0]/180); //Y=y1*sin(L)
patchWithin[I,2]:=StarveData[I,1]; //Z=x
//直角坐标系下的外壁数据
PatchOut[I,0]:=PatchWithin[I,0]+StarveData[I,3]*cos(pi*StarveData[I,0]/180);
PatchOut[I,1]:=patchWithin[I,1]+StarveData[I,3]*sin(pi*StarveData[I,0]/180);
PatchOut[I,2]:=PatchWithin[I,2]; //外壁半径为内壁半径加壁厚
end;
glPushAttrib(GL_ENABLE_BIT or GL_EVAL_BIT);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_MAP2_TEXTURE_COORD_2);
glPushMatrix;
glRotatef(270.0, 1.0, 0.0, 0.0);
glScalef(0.5 * Scale, 0.5 * Scale, 0.5 * Scale);
glTranslatef(0.0, 0.0, -1.5);
for N:=0 to 5 do //每相同深度的点有25个,可组成6×12共72个16点控制块
begin
for I := 0 to 11 do //相同深度的点组成12个4*4控制块
begin
for J := 0 to 3 do
begin
for K := 0 to 3 do
begin
for L := 0 to 2 do
begin
//包含正负180度的特别4×4控制块
if I=11 then // 在正负180度时控制块需要首尾衔接,即相同深度的第12个
//控制块的尾部8个控制点和第1个控制块的首部8个控制点相同
begin
P1[J,0,L]:=patchWithin[50*N+22+25*J,L]; //p1:内壁
P1[J,1,L]:=patchWithin[50*N+23+25*J,L];
P1[J,2,L]:=patchWithin[50*N+24+25*J,L];
P1[J,3,L]:=patchWithin[50*N+1+25*J,L];
Q1[J,0,L]:=patchout[50*N+22+25*J,L]; //Q1:外壁
Q1[J,1,L]:=patchout[50*N+23+25*J,L];
Q1[J,2,L]:=patchout[50*N+24+25*J,L];
Q1[J,3,L]:=patchout[50*N+1+25*J,L];
end;
//不包含正负180度时的4×4控制块
if I<11 then
begin
//内壁控制块的点
P1[J, K, L] := patchWithin[50*N+2*I+25*J+K,L];
//外壁控制块的点
Q1[J, K, L] := patchOut[50*N+2*I+25*J+K,L];
end;
end; //end L
end; //end K
end; // end J
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, @StarveTex);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, @P1[0, 0, 0]);
glMapGrid2f(Grid, 0.0, 1.0, Grid, 0.0, 1.0); //定义将格子等分成Grid份
glEvalMesh2(ShadeType, 0, Grid, 0, Grid); //从格子的起始点到终止点全部画出
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, @Q1[0, 0, 0]);
glEvalMesh2(ShadeType, 0, Grid, 0, Grid);
end; //end I
end; // end N
glPopMatrix;
glPopAttrib;
end; { Teapot }
procedure TForm1.FormPaint(Sender: TObject);
begin
glClearcolor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glRotatef(ax,1,0,0);
glRotatef(ay,0,1,0);
glScalef(scale,scale,scale);
glColor3f(1,1,0);
StarvePot(14,0.2,GL_Fill);
glfinish;
pageflip;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
L.free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InitGL;
Onresize(self);
L:=TCGlight.Create(GL_light0);
L.position:=cgVector(0,0,-1);
L.Diffuse:=cgColorf(1,1,1,1);
L.Infinite:=False;
L.Enable;
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
GetCursorPos(m);
m:=ScreenToClient(m);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
ay:=ay+(X-m.X);
ax:=ax+(Y-m.Y);
end
else if ssRight in Shift then
begin
scale:=scale+(Y-m.Y)/50;
if scale<0 then scale:=0;
end;
m:=Point(X,Y);
Paint;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glviewport(0,0,ClientWidth,ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPersPective(60,ClientWidth/ClientHeight,1,1);
glMatrixMode(GL_MODELVIEW);
paint;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
paint;
end;
end.
//根据模型数据,用OpenGL画图。该模型是一个两头细,中间粗的柱状转炉,提供的数据是
//子午面直角坐标系下的值,需要转化到空间直角坐标系下去。
//采用画Bezier曲面的库函数来画图,画出的图形总是有许多"转折点",而不是一个光滑的炉
//子形状,而且,我很想让图形经过每一个控制点,以便于以后根据控制点做图形交互。
//这在Bezier曲面方式下不知道是不是注定行不通。试着用Nurbs曲面方式,却发现给出的
//PGLUnurbs型的变量编译时Delphi 5根本不认识它,而库GLU中明明又是定义了该类型的。
//另外,炉子本来是有底的,该代码没有包含画炉子的底,不知道如何画出。
//画出的图形转动时有重影,不知如何消除它。
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs,ExtCtrls,Menus,GL,GLU,cgLight,cgWindow,Glut,cgTypes;
type
TGLfloat3v =
array[0..2] of GLfloat;
TInteger3v =
array[0..2] of Integer;
TForm1 = class(TCGForm)
Timer1: TTimer;
procedure FormPaint(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
procedure FormResize(Sender: TObject);
procedure Timer1Timer(Sender: TObject);
private
{ Private declarations }
public
procedure StarvePot(Grid : GLint; Scale : GLdouble; ShadeType : GLenum);
{ Public declarations }
end;
var
Form1: TForm1;
L:TcgLight;
patchwithin,patchOut: Array[0..349,0..2] of GLfloat; //内壁和外壁控制点,各350个
ax:integer=0; //绕x轴的旋转变量
ay:integer=0; //绕Y轴的旋转变量
m:Tpoint; //鼠标位置
Scale:single=1; //缩放比例的系数
const
MaxNumber:GLInt=350; //控制点的数目
StarveTex : //定义纹理
Array[0..1, 0..1, 0..1] of GLfloat =
( ((0, 0), (1, 0)),
((0, 1), (1, 1)) );
pi:
GLfloat=3.14159265;
StarveData : //给出了350个控制点,该转炉是一个旋转体,转炉的控制点是
//子午面直角坐标下的数据,所谓子午面直角坐标系,就是用母线和轴组成的平面
//将旋转体剖成多个小块,小块从-180度到+180度,类似于沿经线划分地球,每一小块
//以母线和旋转轴组成的面为X-Y平面直角坐标系,原点取旋转轴上深度为0的点。
//此处将转炉从-180到+180分成24份,控制点P(L,x,y1,y2):L代表该点的度数,
//x代表深度,y1代表该点所在的圆弧半径,y2代表该点的壁厚。炉子是有厚度的,
//当炉子竖直放置时,P1(L,x,y1)定义了炉子内壁上P1点的位置,而Q1(L,x,y1+y2)则
//定义了与P1点对应的炉子外壁Q1点的位置。
//在将子午面直角坐标系上的控制点P(L,x,y1,y2)转化到空间直角坐标系下的内壁控制点P1(X1,Y1,Z1)
//和外壁控制点Q1(X2,Y2,Z2)时,对P1点,有:X1=y1×cos(L),Y1=y1*sin(L),Z1=x;
//对于Q1,有: X2=(y1+y2)*cos(L),Y2=(y1+y2)*sin(L),Z2=x.
Array[0..349, 0..3] of GLfloat =
( ( -180, -2.0, 2.0, 0.7), // 1
( -165, -2.0, 2.0, 0.7), //四个值依次代表度数,深度,内壁半径,壁厚
( -150, -2.0, 2.0, 0.7), //每相同深度取25个点,实际上第1点和第25点是重合的,
//为简便计,将同一深度内壁半径
( -135, -2.0, 2.0, 0.7), //和壁厚设成相同的 .
( -120, -2.0, 2.0, 0.7), //在用Bezier库函数画图时,取的4×4控制点是按
( -105, -2.0, 2.0, 0.7), //每相同深度各取4个,各控制块的度数要对应,深度上依次推进的。
( -90, -2.0, 2.0, 0.7), //相同深度的12块4*4控制块组成一个封闭的环面,在深度上推进6次,
//共有6*12个控制块来组成转炉的内壁面,外壁面也是6×12个控制块。
( -75, -2.0, 2.0, 0.7),
//如第1个内壁面控制块从StarveData的第1,2,3,4,26,27,28,29,51,52,52,54, 76,77,78,79控制点取数,
(-60, -2.0, 2.0, 0.7),
( -45, -2.0, 2.0, 0.7), //第2个块从第3,4,5,6,28,29,30,31,53,54,55,56,78,79,80,81取数。。。,
(-30, -2.0, 2.0, 0.7),// 第11个块从第21,22,23,24,46,47,48,49,71,72,73,74,96,97,98,99取数,
( -15, -2.0, 2.0, 0.7), //特别的,第12块从23,24,25,2,48,49,50,27,73,74,75,52,98,99,100,77取数。。。
( 0, -2.0, 2.0, 0.7), //深度推进后的第13块从51,52,53,54,76,77,78,79,101,102,103,104,126,127,128,129取数
( 15, -2.0, 2.0, 0.7),
( 30, -2.0, 2.0, 0.7),
( 45, -2.0, 2.0, 0.7),
( 60, -2.0, 2.0, 0.7),
( 75, -2.0, 2.0, 0.7),
( 90, -2.0, 2.0, 0.7),
( 105, -2.0, 2.0, 0.7),
( 120, -2.0, 2.0, 0.7),
( 135, -2.0, 2.0, 0.7),
( 150, -2.0, 2.0, 0.7),
( 165, -2.0, 2.0, 0.7),
( 180, -2.0, 2.0, 0.7),
( -180, -1.0, 2.5, 0.7), //26
( -165, -1.0, 2.5, 0.7),
( -150, -1.0, 2.5, 0.7),
( -135, -1.0, 2.5, 0.7),
( -120, -1.0, 2.5, 0.7),
( -105, -1.0, 2.5, 0.7),
( -90, -1.0, 2.5, 0.7),
( -75, -1.0, 2.5, 0.7),
( -60, -1.0, 2.5, 0.7),
( -45, -1.0, 2.5, 0.7),
( -30, -1.0, 2.5, 0.7),
( -15, -1.0, 2.5, 0.7),
( 0, -1.0, 2.5, 0.7),
( 15, -1.0, 2.5, 0.7),
( 30, -1.0, 2.5, 0.7),
( 45, -1.0, 2.5, 0.7),
( 60, -1.0, 2.5, 0.7),
( 75, -1.0, 2.5, 0.7),
( 90, -1.0, 2.5, 0.7),
( 105, -1.0, 2.5, 0.7),
( 120, -1.0, 2.5, 0.7),
( 135, -1.0, 2.5, 0.7),
( 150, -1.0, 2.5, 0.7),
( 165, -1.0, 2.5, 0.7),
( 180, -1.0, 2.5, 0.7),
( -180, 0, 3.0, 0.7), // 51
( -165, 0, 3.0, 0.7),
( -150, 0, 3.0, 0.7),
( -135, 0, 3.0, 0.7),
( -120, 0, 3.0, 0.7),
( -105, 0, 3.0, 0.7),
( -90, 0, 3.0, 0.7),
( -75, 0, 3.0, 0.7),
( -60, 0, 3.0, 0.7),
( -45, 0, 3.0, 0.7),
( -30, 0, 3.0, 0.7),
( -15, 0, 3.0, 0.7),
( 0, 0, 3.0, 0.7),
( 15, 0, 3.0, 0.7),
( 30, 0, 3.0, 0.7),
( 45, 0, 3.0, 0.7),
( 60, 0, 3.0, 0.7),
( 75, 0, 3.0, 0.7),
( 90, 0, 3.0, 0.7),
( 105, 0, 3.0, 0.7),
( 120, 0, 3.0, 0.7),
( 135, 0, 3.0, 0.7),
( 150, 0, 3.0, 0.7),
( 165, 0, 3.0, 0.7),
( 180, 0, 3.0, 0.7),
( -180, 1, 3.2, 0.7), // 76
( -165, 1, 3.2, 0.7),
( -150, 1, 3.2, 0.7),
( -135, 1, 3.2, 0.7),
( -120, 1, 3.2, 0.7),
( -105, 1, 3.2, 0.7),
( -90, 1, 3.2, 0.7),
( -75, 1, 3.2, 0.7),
( -60, 1, 3.2, 0.7),
( -45, 1, 3.2, 0.7),
( -30, 1, 3.2, 0.7),
( -15, 1, 3.2, 0.7),
( 0, 1, 3.2, 0.7),
( 15, 1, 3.2, 0.7),
( 30, 1, 3.2, 0.7),
( 45, 1, 3.2, 0.7),
( 60, 1, 3.2, 0.7),
( 75, 1, 3.2, 0.7),
( 90, 1, 3.2, 0.7),
( 105, 1, 3.2, 0.7),
( 120, 1, 3.2, 0.7),
( 135, 1, 3.2, 0.7),
( 150, 1, 3.2, 0.7),
( 165, 1, 3.2, 0.7),
( 180, 1, 3.2, 0.7),
( -180, 1.5, 3.4, 0.7), //101
( -165, 1.5, 3.4, 0.7),
( -150, 1.5, 3.4, 0.7),
( -135, 1.5, 3.4, 0.7),
( -120, 1.5, 3.4, 0.7),
( -105, 1.5, 3.4, 0.7),
( -90, 1.5, 3.4, 0.7),
( -75, 1.5, 3.4, 0.7),
( -60, 1.5, 3.4, 0.7),
( -45, 1.5, 3.4, 0.7),
( -30, 1.5, 3.4, 0.7),
( -15, 1.5, 3.4, 0.7),
( 0, 1.5, 3.4, 0.7),
( 15, 1.5, 3.4, 0.7),
( 30, 1.5, 3.4, 0.7),
( 45, 1.5, 3.4, 0.7),
( 60, 1.5, 3.4, 0.7),
( 75, 1.5, 3.4, 0.7),
( 90, 1.5, 3.4, 0.7),
( 105, 1.5, 3.4, 0.7),
( 120, 1.5, 3.4, 0.7),
( 135, 1.5, 3.4, 0.7),
( 150, 1.5, 3.4, 0.7),
( 165, 1.5, 3.4, 0.7),
( 180, 1.5, 3.4, 0.7),
( -180, 2.0, 3.4, 0.7), //126
( -165, 2.0, 3.4, 0.7),
( -150, 2.0, 3.4, 0.7),
( -135, 2.0, 3.4, 0.7),
( -120, 2.0, 3.4, 0.7),
( -105, 2.0, 3.4, 0.7),
( -90, 2.0, 3.4, 0.7),
( -75, 2.0, 3.4, 0.7),
( -60, 2.0, 3.4, 0.7),
( -45, 2.0, 3.4, 0.7),
( -30, 2.0, 3.4, 0.7),
( -15, 2.0, 3.4, 0.7),
( 0, 2.0, 3.4, 0.7),
( 15, 2.0, 3.4, 0.7),
( 30, 2.0, 3.4, 0.7),
( 45, 2.0, 3.4, 0.7),
( 60, 2.0, 3.4, 0.7),
( 75, 2.0, 3.4, 0.7),
( 90, 2.0, 3.4, 0.7),
( 105, 2.0, 3.4, 0.7),
( 120, 2.0, 3.4, 0.7),
( 135, 2.0, 3.4, 0.7),
( 150, 2.0, 3.4, 0.7),
( 165, 2.0, 3.4, 0.7),
( 180, 2.0, 3.4, 0.7),
( -180, 2.5, 3.4, 0.7), //151
( -165, 2.5, 3.4, 0.7),
( -150, 2.5, 3.4, 0.7),
( -135, 2.5, 3.4, 0.7),
( -120, 2.5, 3.4, 0.7),
( -105, 2.5, 3.4, 0.7),
( -90, 2.5, 3.4, 0.7),
( -75, 2.5, 3.4, 0.7),
( -60, 2.5, 3.4, 0.7),
( -45, 2.5, 3.4, 0.7),
( -30, 2.5, 3.4, 0.7),
( -15, 2.5, 3.4, 0.7),
( 0, 2.5, 3.4, 0.7),
( 15, 2.5, 3.4, 0.7),
( 30, 2.5, 3.4, 0.7),
( 45, 2.5, 3.4, 0.7),
( 60, 2.5, 3.4, 0.7),
( 75, 2.5, 3.4, 0.7),
( 90, 2.5, 3.4, 0.7),
( 105, 2.5, 3.4, 0.7),
( 120, 2.5, 3.4, 0.7),
( 135, 2.5, 3.4, 0.7),
( 150, 2.5, 3.4, 0.7),
( 165, 2.5, 3.4, 0.7),
( 180, 2.5, 3.4, 0.7),
( -180, 5.5, 3.4, 0.7), //176
( -165, 5.5, 3.4, 0.7),
( -150, 5.5, 3.4, 0.7),
( -135, 5.5, 3.4, 0.7),
( -120, 5.5, 3.4, 0.7),
( -105, 5.5, 3.4, 0.7),
( -90, 5.5, 3.4, 0.7),
( -75, 5.5, 3.4, 0.7),
( -60, 5.5, 3.4, 0.7),
( -45, 5.5, 3.4, 0.7),
( -30, 5.5, 3.4, 0.7),
( -15, 5.5, 3.4, 0.7),
( 0, 5.5, 3.4, 0.7),
( 15, 5.5, 3.4, 0.7),
( 30, 5.5, 3.4, 0.7),
( 45, 5.5, 3.4, 0.7),
( 60, 5.5, 3.4, 0.7),
( 75, 5.5, 3.4, 0.7),
( 90, 5.5, 3.4, 0.7),
( 105, 5.5, 3.4, 0.7),
( 120, 5.5, 3.4, 0.7),
( 135, 5.5, 3.4, 0.7),
( 150, 5.5, 3.4, 0.7),
( 165, 5.5, 3.4, 0.7),
( 180, 5.5, 3.4, 0.7),
( -180, 6.5, 3.3, 0.7), //201
( -165, 6.5, 3.3, 0.7),
( -150, 6.5, 3.3, 0.7),
( -135, 6.5, 3.3, 0.7),
( -120, 6.5, 3.3, 0.7),
( -105, 6.5, 3.3, 0.7),
( -90, 6.5, 3.3, 0.7),
( -75, 6.5, 3.3, 0.7),
( -60, 6.5, 3.3, 0.7),
( -45, 6.5, 3.3, 0.7),
( -30, 6.5, 3.3, 0.7),
( -15, 6.5, 3.3, 0.7),
( 0, 6.5, 3.3, 0.7),
( 15, 6.5, 3.3, 0.7),
( 30, 6.5, 3.3, 0.7),
( 45, 6.5, 3.3, 0.7),
( 60, 6.5, 3.3, 0.7),
( 75, 6.5, 3.3, 0.7),
( 90, 6.5, 3.3, 0.7),
( 105, 6.5, 3.3, 0.7),
( 120, 6.5, 3.3, 0.7),
( 135, 6.5, 3.3, 0.7),
( 150, 6.5, 3.3, 0.7),
( 165, 6.5, 3.3, 0.7),
( 180, 6.5, 3.3, 0.7),
( -180, 6.5, 3.3, 0.7), //226
( -165, 6.5, 3.3, 0.7),
( -150, 6.5, 3.3, 0.7),
( -135, 6.5, 3.3, 0.7),
( -120, 6.5, 3.3, 0.7),
( -105, 6.5, 3.3, 0.7),
( -90, 6.5, 3.3, 0.7),
( -75, 6.5, 3.3, 0.7),
( -60, 6.5, 3.3, 0.7),
( -45, 6.5, 3.3, 0.7),
( -30, 6.5, 3.3, 0.7),
( -15, 6.5, 3.3, 0.7),
( 0, 6.5, 3.3, 0.7),
( 15, 6.5, 3.3, 0.7),
( 30, 6.5, 3.3, 0.7),
( 45, 6.5, 3.3, 0.7),
( 60, 6.5, 3.3, 0.7),
( 75, 6.5, 3.3, 0.7),
( 90, 6.5, 3.3, 0.7),
( 105, 6.5, 3.3, 0.7),
( 120, 6.5, 3.3, 0.7),
( 135, 6.5, 3.3, 0.7),
( 150, 6.5, 3.3, 0.7),
( 165, 6.5, 3.3, 0.7),
( 180, 6.5, 3.3, 0.7),
( -180, 7.0, 3.0, 0.7), //251
( -165, 7.0, 3.0, 0.7),
( -150, 7.0, 3.0, 0.7),
( -135, 7.0, 3.0, 0.7),
( -120, 7.0, 3.0, 0.7),
( -105, 7.0, 3.0, 0.7),
( -90, 7.0, 3.0, 0.7),
( -75, 7.0, 3.0, 0.7),
( -60, 7.0, 3.0, 0.7),
( -45, 7.0, 3.0, 0.7),
( -30, 7.0, 3.0, 0.7),
( -15, 7.0, 3.0, 0.7),
( 0, 7.0, 3.0, 0.7),
( 15, 7.0, 3.0, 0.7),
( 30, 7.0, 3.0, 0.7),
( 45, 7.0, 3.0, 0.7),
( 60, 7.0, 3.0, 0.7),
( 75, 7.0, 3.0, 0.7),
( 90, 7.0, 3.0, 0.7),
( 105, 7.0, 3.0, 0.7),
( 120, 7.0, 3.0, 0.7),
( 135, 7.0, 3.0, 0.7),
( 150, 7.0, 3.0, 0.7),
( 165, 7.0, 3.0, 0.7),
( 180, 7.0 , 3.0, 0.7),
( -180, 7.5, 3.0, 0.7), //276
( -165, 7.5, 3.0, 0.7),
( -150, 7.5, 3.0, 0.7),
( -135, 7.5, 3.0, 0.7),
( -120, 7.5, 3.0, 0.7),
( -105, 7.5, 3.0, 0.7),
( -90, 7.5, 3.0, 0.7),
( -75, 7.5, 3.0, 0.7),
( -60, 7.5, 3.0, 0.7),
( -45, 7.5, 3.0, 0.7),
( -30, 7.5, 3.0, 0.7),
( -15, 7.5, 3.0, 0.7),
( 0, 7.5, 3.0, 0.7),
( 15, 7.5, 3.0, 0.7),
( 30, 7.5, 3.0, 0.7),
( 45, 7.5, 3.0, 0.7),
( 60, 7.5, 3.0, 0.7),
( 75, 7.5, 3.0, 0.7),
( 90, 7.5, 3.0, 0.7),
( 105, 7.5, 3.0, 0.7),
( 120, 7.5, 3.0, 0.7),
( 135, 7.5, 3.0, 0.7),
( 150, 7.5, 3.0, 0.7),
( 165, 7.5, 3.0, 0.7),
( 180, 7.5, 3.0, 0.7),
( -180, 8.0, 2.8, 0.7), //301
( -165, 8.0, 2.8, 0.7),
( -150, 8.0, 2.8, 0.7),
( -135, 8.0, 2.8, 0.7),
( -120, 8.0, 2.8, 0.7),
( -105, 8.0, 2.8, 0.7),
( -90, 8.0, 2.8, 0.7),
( -75, 8.0, 2.8, 0.7),
( -60, 8.0, 2.8, 0.7),
( -45, 8.0, 2.8, 0.7),
( -30, 8.0, 2.8, 0.7),
( -15, 8.0, 2.8, 0.7),
( 0, 8.0, 2.8, 0.7),
( 15, 8.0, 2.8, 0.7),
( 30, 8.0, 2.8, 0.7),
( 45, 8.0, 2.8, 0.7),
( 60, 8.0, 2.8, 0.7),
( 75, 8.0, 2.8, 0.7),
( 90, 8.0, 2.8, 0.7),
( 105, 8.0, 2.8, 0.7),
( 120, 8.0, 2.8, 0.7),
( 135, 8.0, 2.8, 0.7),
( 150, 8.0, 2.8, 0.7),
( 165, 8.0, 2.8, 0.7),
( 180, 8.0, 2.8, 0.7),
( -180, 8.5, 2.8, 0.7), //326
( -165, 8.5, 2.8, 0.7),
( -150, 8.5, 2.8, 0.7),
( -135, 8.5, 2.8, 0.7),
( -120, 8.5, 2.8, 0.7),
( -105, 8.5, 2.8, 0.7),
( -90, 8.5, 2.8, 0.7),
( -75, 8.5, 2.8, 0.7),
( -60, 8.5, 2.8, 0.7),
( -45, 8.5, 2.8, 0.7),
( -30, 8.5, 2.8, 0.7),
( -15, 8.5, 2.8, 0.7),
( 0, 8.5, 2.8, 0.7),
( 15, 8.5, 2.8, 0.7),
( 30, 8.5, 2.8, 0.7),
( 45, 8.5, 2.8, 0.7),
( 50, 8.5, 2.8, 0.7),
( 75, 8.5, 2.8, 0.7),
( 90, 8.5, 2.8, 0.7),
( 105, 8.5, 2.8, 0.7),
( 120, 8.5, 2.8, 0.7),
( 135, 8.5, 2.8, 0.7),
( 150, 8.5, 2.8, 0.7),
( 165, 8.5, 2.8, 0.7),
( 180, 8.5, 2.8, 0.7) //350
);
implementation
{$R *.DFM}
procedure TForm1.StarvePot(Grid : GLint; Scale : GLdouble; ShadeType : GLenum);
//由于用bezier曲面画图时,前一个4×4控制块和后一个在衔接时很难满足C1连续,出现了
//一系列的”不能“,不能画出光滑的图形,而且图形不经过大多数控制点。我试着用Nurbs
//曲面方式的GLuNurbsSurface库函数来画,结果定义的PGLUnurbs对象编译都通不过。不知道
//是抱定bezier法到底,还是用Nurbs法或者其他别的方法更合适。
var
P1, Q1 : Array[0..3, 0..3, 0..2] of GLfloat;
N,I, J, K, L : GLInt;
begin { Teapot }
//首先将数据化至空间直角坐标系下
for I:=0 to MaxNumber-1 do
begin
//直角坐标系下的内壁数据
PatchWithin[I,0]:=StarveData[I,2]*cos(pi*StarveData[I,0]/180); //X=y1*cos(L)
patchWithin[I,1]:=StarveData[I,2]*sin(pi*StarveData[I,0]/180); //Y=y1*sin(L)
patchWithin[I,2]:=StarveData[I,1]; //Z=x
//直角坐标系下的外壁数据
PatchOut[I,0]:=PatchWithin[I,0]+StarveData[I,3]*cos(pi*StarveData[I,0]/180);
PatchOut[I,1]:=patchWithin[I,1]+StarveData[I,3]*sin(pi*StarveData[I,0]/180);
PatchOut[I,2]:=PatchWithin[I,2]; //外壁半径为内壁半径加壁厚
end;
glPushAttrib(GL_ENABLE_BIT or GL_EVAL_BIT);
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glEnable(GL_MAP2_VERTEX_3);
glEnable(GL_MAP2_TEXTURE_COORD_2);
glPushMatrix;
glRotatef(270.0, 1.0, 0.0, 0.0);
glScalef(0.5 * Scale, 0.5 * Scale, 0.5 * Scale);
glTranslatef(0.0, 0.0, -1.5);
for N:=0 to 5 do //每相同深度的点有25个,可组成6×12共72个16点控制块
begin
for I := 0 to 11 do //相同深度的点组成12个4*4控制块
begin
for J := 0 to 3 do
begin
for K := 0 to 3 do
begin
for L := 0 to 2 do
begin
//包含正负180度的特别4×4控制块
if I=11 then // 在正负180度时控制块需要首尾衔接,即相同深度的第12个
//控制块的尾部8个控制点和第1个控制块的首部8个控制点相同
begin
P1[J,0,L]:=patchWithin[50*N+22+25*J,L]; //p1:内壁
P1[J,1,L]:=patchWithin[50*N+23+25*J,L];
P1[J,2,L]:=patchWithin[50*N+24+25*J,L];
P1[J,3,L]:=patchWithin[50*N+1+25*J,L];
Q1[J,0,L]:=patchout[50*N+22+25*J,L]; //Q1:外壁
Q1[J,1,L]:=patchout[50*N+23+25*J,L];
Q1[J,2,L]:=patchout[50*N+24+25*J,L];
Q1[J,3,L]:=patchout[50*N+1+25*J,L];
end;
//不包含正负180度时的4×4控制块
if I<11 then
begin
//内壁控制块的点
P1[J, K, L] := patchWithin[50*N+2*I+25*J+K,L];
//外壁控制块的点
Q1[J, K, L] := patchOut[50*N+2*I+25*J+K,L];
end;
end; //end L
end; //end K
end; // end J
glMap2f(GL_MAP2_TEXTURE_COORD_2, 0, 1, 2, 2, 0, 1, 4, 2, @StarveTex);
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, @P1[0, 0, 0]);
glMapGrid2f(Grid, 0.0, 1.0, Grid, 0.0, 1.0); //定义将格子等分成Grid份
glEvalMesh2(ShadeType, 0, Grid, 0, Grid); //从格子的起始点到终止点全部画出
glMap2f(GL_MAP2_VERTEX_3, 0, 1, 3, 4, 0, 1, 12, 4, @Q1[0, 0, 0]);
glEvalMesh2(ShadeType, 0, Grid, 0, Grid);
end; //end I
end; // end N
glPopMatrix;
glPopAttrib;
end; { Teapot }
procedure TForm1.FormPaint(Sender: TObject);
begin
glClearcolor(1,0,0,1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
glLoadIdentity;
glRotatef(ax,1,0,0);
glRotatef(ay,0,1,0);
glScalef(scale,scale,scale);
glColor3f(1,1,0);
StarvePot(14,0.2,GL_Fill);
glfinish;
pageflip;
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
L.free;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
InitGL;
Onresize(self);
L:=TCGlight.Create(GL_light0);
L.position:=cgVector(0,0,-1);
L.Diffuse:=cgColorf(1,1,1,1);
L.Infinite:=False;
L.Enable;
glEnable(GL_AUTO_NORMAL);
glEnable(GL_NORMALIZE);
glLightModeli(GL_LIGHT_MODEL_TWO_SIDE,1);
glColorMaterial(GL_FRONT_AND_BACK,GL_DIFFUSE);
glEnable(GL_COLOR_MATERIAL);
GetCursorPos(m);
m:=ScreenToClient(m);
end;
procedure TForm1.FormMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if ssLeft in Shift then
begin
ay:=ay+(X-m.X);
ax:=ax+(Y-m.Y);
end
else if ssRight in Shift then
begin
scale:=scale+(Y-m.Y)/50;
if scale<0 then scale:=0;
end;
m:=Point(X,Y);
Paint;
end;
procedure TForm1.FormResize(Sender: TObject);
begin
glviewport(0,0,ClientWidth,ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
gluPersPective(60,ClientWidth/ClientHeight,1,1);
glMatrixMode(GL_MODELVIEW);
paint;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
paint;
end;
end.