Построить цилиндр, как поверхность вращения в среде Builder C++

Задание: построить цилиндр, как поверхность вращения в C++. Основание цилиндра находится в плоскости XZ. Центр основания совпадает с началом координат. Одно из оснований совпадает с началом координат.

Построить sweep поверхность:
Кривая ссылки – составная кривая Безье 3-ей степени по 12 опорным точкам, выполнить условие гладкости кривой.
Направляющая – открытый В-сплайн 3-ей степени по 10 опорным точкам, параметризация неравномерная.
Образующая – составная кривая Безье 4-ой степени по 11 опорным точкам (образующая связана с профилем).

Алгоритм построения цилиндра, как поверхность вращения

1) Строим следующие кривые: кривая ссылки, направляющая и образующая кривая.

2) Строим в плоскости XZ окружность с центром в начале координат.

3) Далее мы определяем нормаль к направляющей кривой в каждой точке. Определив нормаль, мы знаем плоскость (Ax+By+Cz+D=0), в которой будем строить профиль (окружность).

4) Далее определяем углы поворота через косинусы, используя следующее соотношения:

5) Чтобы построить окружность в нужной нам плоскости

Интерфейс разработанной программы

Вы можете задать значения опорных точек для построения всех трех кривых.

Чтобы построить поверхность необходимо нажать на кнопку «построить» после чего откроется новое окно, в котором будут построены кривые и цилиндр.

Пример работы программы
Синяя линия – кривая ссылки; зеленая линия – образующая; красная линия — направляющая


Красная прямая – ось X
Синяя прямая – ось Y
Зеленая прямая – ось Z

Другой вид этого же цилиндра и кривых:

Исходный код программы с пояснениями

//—————————————————————————

#include
#pragma hdrstop

#include «Unit1.h»
#include «Unit2.h»
#include «math.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»
TForm1 *Form1;

//—————————————————————————
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//—————————————————————————

void __fastcall TForm1::FormCreate(TObject *Sender)
{
//———-Задаем значения по умолчанию————-
StringGrid1->Cells[0][0]=’X’;
StringGrid1->Cells[0][1]=’Y’;
StringGrid1->Cells[0][2]=’Z’; //кривая ссылки

StringGrid2->Cells[0][0]=’X’;
StringGrid2->Cells[0][1]=’Y’;
StringGrid2->Cells[0][2]=’Z’; //направляющая

StringGrid3->Cells[0][0]=’X’;
StringGrid3->Cells[0][1]=’Y’;
StringGrid3->Cells[0][2]=’Z’; //образующая

//———-инициализация значений по умолчанию (кривая ссылки)—————-
StringGrid1->Cells[1][0]=IntToStr(-5);
StringGrid1->Cells[2][0]=IntToStr(10);
StringGrid1->Cells[3][0]=IntToStr(35);
StringGrid1->Cells[4][0]=IntToStr(40);
StringGrid1->Cells[5][0]=IntToStr(43);
StringGrid1->Cells[6][0]=IntToStr(35);
StringGrid1->Cells[7][0]=IntToStr(60);
StringGrid1->Cells[8][0]=IntToStr(65);
StringGrid1->Cells[9][0]=IntToStr(70);
StringGrid1->Cells[10][0]=IntToStr(90);
StringGrid1->Cells[11][0]=IntToStr(110);
StringGrid1->Cells[12][0]=IntToStr(80);

StringGrid1->Cells[1][1]=IntToStr(-15);
StringGrid1->Cells[2][1]=IntToStr(-25);
StringGrid1->Cells[3][1]=IntToStr(-35);
StringGrid1->Cells[4][1]=IntToStr(-55);
StringGrid1->Cells[5][1]=IntToStr(-60);
StringGrid1->Cells[6][1]=IntToStr(-64);
StringGrid1->Cells[7][1]=IntToStr(-76);
StringGrid1->Cells[8][1]=IntToStr(-97);
StringGrid1->Cells[9][1]=IntToStr(-100);
StringGrid1->Cells[10][1]=IntToStr(-94);
StringGrid1->Cells[11][1]=IntToStr(-86);
StringGrid1->Cells[12][1]=IntToStr(-70);

StringGrid1->Cells[1][2]=IntToStr(-5);
StringGrid1->Cells[2][2]=IntToStr(-10);
StringGrid1->Cells[3][2]=IntToStr(20);
StringGrid1->Cells[4][2]=IntToStr(25);
StringGrid1->Cells[5][2]=IntToStr(40);
StringGrid1->Cells[6][2]=IntToStr(30);
StringGrid1->Cells[7][2]=IntToStr(7);
StringGrid1->Cells[8][2]=IntToStr(10);
StringGrid1->Cells[9][2]=IntToStr(30);
StringGrid1->Cells[10][2]=IntToStr(20);
StringGrid1->Cells[11][2]=IntToStr(70);
StringGrid1->Cells[12][2]=IntToStr(100);
//———-инициализация значений по умолчанию (направляющая)—————-
StringGrid2->Cells[1][0]=IntToStr(0);
StringGrid2->Cells[2][0]=IntToStr(2);
StringGrid2->Cells[3][0]=IntToStr(7);
StringGrid2->Cells[4][0]=IntToStr(5);
StringGrid2->Cells[5][0]=IntToStr(7);
StringGrid2->Cells[6][0]=IntToStr(5);
StringGrid2->Cells[7][0]=IntToStr(6);
StringGrid2->Cells[8][0]=IntToStr(4);
StringGrid2->Cells[9][0]=IntToStr(5);
StringGrid2->Cells[10][0]=IntToStr(6);

StringGrid2->Cells[1][1]=IntToStr(0);
StringGrid2->Cells[2][1]=IntToStr(-2);
StringGrid2->Cells[3][1]=IntToStr(-6);
StringGrid2->Cells[4][1]=IntToStr(-9);
StringGrid2->Cells[5][1]=IntToStr(-10);
StringGrid2->Cells[6][1]=IntToStr(-15);
StringGrid2->Cells[7][1]=IntToStr(-25);
StringGrid2->Cells[8][1]=IntToStr(-30);
StringGrid2->Cells[9][1]=IntToStr(-40);
StringGrid2->Cells[10][1]=IntToStr(-90);

StringGrid2->Cells[1][2]=IntToStr(0);
StringGrid2->Cells[2][2]=IntToStr(2);
StringGrid2->Cells[3][2]=IntToStr(3);
StringGrid2->Cells[4][2]=IntToStr(5);
StringGrid2->Cells[5][2]=IntToStr(4);
StringGrid2->Cells[6][2]=IntToStr(5);
StringGrid2->Cells[7][2]=IntToStr(4);
StringGrid2->Cells[8][2]=IntToStr(6);
StringGrid2->Cells[9][2]=IntToStr(4);
StringGrid2->Cells[10][2]=IntToStr(5);

//———-инициализация значений по умолчанию (обращующая)—————-
StringGrid3->Cells[1][0]=IntToStr(0);
StringGrid3->Cells[2][0]=IntToStr(-3);
StringGrid3->Cells[3][0]=IntToStr(-1);
StringGrid3->Cells[4][0]=IntToStr(3);
StringGrid3->Cells[5][0]=IntToStr(7);
StringGrid3->Cells[6][0]=IntToStr(5);
StringGrid3->Cells[7][0]=IntToStr(-4);
StringGrid3->Cells[8][0]=IntToStr(-10);
StringGrid3->Cells[9][0]=IntToStr(-12);
StringGrid3->Cells[10][0]=IntToStr(-13);
StringGrid3->Cells[11][0]=IntToStr(-15);

StringGrid3->Cells[1][1]=IntToStr(0);
StringGrid3->Cells[2][1]=IntToStr(-15);
StringGrid3->Cells[3][1]=IntToStr(-35);
StringGrid3->Cells[4][1]=IntToStr(-45);
StringGrid3->Cells[5][1]=IntToStr(-55);
StringGrid3->Cells[6][1]=IntToStr(-60);
StringGrid3->Cells[7][1]=IntToStr(-70);
StringGrid3->Cells[8][1]=IntToStr(-80);
StringGrid3->Cells[9][1]=IntToStr(-88);
StringGrid3->Cells[10][1]=IntToStr(-99);
StringGrid3->Cells[11][1]=IntToStr(-104);

StringGrid3->Cells[1][2]=IntToStr(0);
StringGrid3->Cells[2][2]=IntToStr(-1);
StringGrid3->Cells[3][2]=IntToStr(4);
StringGrid3->Cells[4][2]=IntToStr(5);
StringGrid3->Cells[5][2]=IntToStr(3);
StringGrid3->Cells[6][2]=IntToStr(8);
StringGrid3->Cells[7][2]=IntToStr(10);
StringGrid3->Cells[8][2]=IntToStr(5);
StringGrid3->Cells[9][2]=IntToStr(12);
StringGrid3->Cells[10][2]=IntToStr(14);
StringGrid3->Cells[11][2]=IntToStr(17);
}
//—————————————————————————
void __fastcall TForm1::Button2Click(TObject *Sender)
{
Form1->Close();
}
//—————————————————————————
void __fastcall TForm1::Button1Click(TObject *Sender)
{
Form2->Show(); //функция открытия формы 2 и построения
}
//—————————————————————————

Форма №2:
//—————————————————————————
#include
#pragma hdrstop

#include «Unit2.h»
#include «Unit1.h»
#include «math.h»
//—————————————————————————
#pragma package(smart_init)
#pragma resource «*.dfm»
TForm2 *Form2;
GLfloat spine[10][3];
GLfloat link[12][3];
GLfloat guide[11][3];
//—————————————————————————
__fastcall TForm2::TForm2(TComponent* Owner)
: TForm(Owner)
{
Application->OnIdle = IdleLoop;
}
//—————————————————————————
void __fastcall TForm2::Button1Click(TObject *Sender)
{
Form2->Close();
}
//—————————————————————————
void __fastcall TForm2::IdleLoop(TObject*, bool& done)
{
done = false;
RenderScene();
SwapBuffers(hDC);
}
//—————————————————————————

bool TForm2::OpenGLInit(void)
{
hDC = GetDC(Handle);
if (hDC == NULL)
return (false);
SetGLPixelFormat(hDC);
hRC = wglCreateContext(hDC);
if (hRC == NULL)
return (false);
wglMakeCurrent( hDC, hRC);
return (true);
}
//—————————————————————————
void TForm2::SetGLPixelFormat( HDC hdc)
{
int PixelFormatIndex;
PIXELFORMATDESCRIPTOR PixelFormat =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,0,0,0,0,0,0,0,
32,
0,0,
PFD_MAIN_PLANE,
0,0,0,0
};
PixelFormatIndex = ChoosePixelFormat(hdc, &PixelFormat);
SetPixelFormat(hdc, PixelFormatIndex, &PixelFormat);
}
//—————————————————————————
void TForm2::SetViewport(bool Perspective)
{
float w,h,Aspect;
w=Width;
h=Height;
if (h == 0)
h=1;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (Perspective)
{
Aspect=(GLfloat)w/(GLfloat)h;
gluPerspective(60.0f,Aspect,1.0f,1000.0f);
}
else
{
if (w <= h) glOrtho(-250.0f,250.0f,-250.0f*h/w,250.0f*h/w,1.0f,1000.0f); else glOrtho(-250.0f*h/w,250.0f*h/w,-250.0f,250.0f,1.0f,1000.0f); } glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } //--------------------------------------------------------------------------- void __fastcall TForm2::FormCreate(TObject *Sender) { m=1;//зум koleso=1; OpenGLInit(); } //--------------------------------------------------------------------------- void __fastcall TForm2::FormResize(TObject *Sender) void __fastcall TForm2::FormResize(TObject *Sender) { float w,h; GLfloat nRange = 100.0; w = ClientWidth; h = ClientHeight; glViewport(0, 0, w, h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if (w <= h) glOrtho (-nRange, nRange, -nRange*h/w, nRange*h/w, -nRange*2.0f, nRange*2.0f); else glOrtho (-nRange*w/h, nRange*w/h, -nRange, nRange, -nRange*2.0f, nRange*2.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } //----------Построение окружности с радиусом r с центром x,y,z в плоскости ax+by+cz------------- void TForm2::Circle(int r, int x, int y, int z, double a, double b, double c) { glPointSize (1); glBegin(GL_LINES); glColor3f (0.0, 0.0, 0.0); double i,x1,y1,z1,x2,y2,z2,a1,b1,c1,tempx1,tempy1,tempz1,tempx2,tempy2,tempz2; if ((a==0)&&(c==0)) {a1=0;c1=0;} else{ a1=-acos(a/sqrt((a*a+b*b+c*c)))+M_PI_2; c1=acos(c/sqrt((a*a+b*b+c*c)))-M_PI_2; } for(i=0;i<180;i++) { //------круг в XZ------- x1=(r*sin(2*i*M_PI/180)); tempx1=x1; x2=(r*sin(2*(i+1)*M_PI/180)); tempx2=x2; y1=(0); tempy1=y1; y2=(0); tempy2=y2; z1=(r*cos(2*i*M_PI/180)); tempz1=z1; z2=(r*cos(2*(i+1)*M_PI/180)); tempz2=z2; //-------поворот Rx---- y1=tempy1*cos(c1)-tempz1*sin(c1); y2=tempy2*cos(c1)-tempz2*sin(c1); z1=tempy1*sin(c1)+tempz1*cos(c1)+z; z2=tempy2*sin(c1)+tempz2*cos(c1)+z; tempy1=y1;tempy2=y2; //------- поворот Rz---- x1=tempx1*cos(a1)-tempy1*sin(a1)+x; x2=tempx2*cos(a1)-tempy2*sin(a1)+x; y1=tempx1*sin(a1)+tempy1*cos(a1)+y; y2=tempx2*sin(a1)+tempy2*cos(a1)+y; glVertex4f(x1,y1,z1,m); glVertex4f(x2,y2,z2,m); } glEnd(); } void TForm2::RenderScene() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glClearColor(1.0f, 1.0f, 1.0f, 1.0f ); glPushMatrix(); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glPolygonMode(GL_FRONT,GL_FILL); glEnable(GL_NORMALIZE); //---------------строим оси координат---------------- glBegin(GL_LINES); glColor3f (0.0, 1.0, 0.0); glVertex4f(0,0,0,m); glVertex4f(0,0,120,m); glColor3f (1.0, 0.0, 0.0); glVertex4f(0,0,0,m); glVertex4f(120,0,0,m); glColor3f (0.0, 0.0, 1.0); glVertex4f(0,0,0,m); glVertex4f(0,60,0,m); glEnd(); //---------------------END---------------------- //---------------загрузка координат в массивы---------------- int i,j,k; for(i=0;i<10;i++) {spine[i][0]=StrToInt(Form1->StringGrid2->Cells[i+1][0]);
spine[i][1]=StrToInt(Form1->StringGrid2->Cells[i+1][1]);
spine[i][2]=StrToInt(Form1->StringGrid2->Cells[i+1][2]);
}
for(i=0;i<11;i++) {guide[i][0]=StrToInt(Form1->StringGrid3->Cells[i+1][0]);
guide[i][1]=StrToInt(Form1->StringGrid3->Cells[i+1][1]);
guide[i][2]=StrToInt(Form1->StringGrid3->Cells[i+1][2]);
}
for(i=0;i<12;i++) {link[i][0]=StrToInt(Form1->StringGrid1->Cells[i+1][0]);
link[i][1]=StrToInt(Form1->StringGrid1->Cells[i+1][1]);
link[i][2]=StrToInt(Form1->StringGrid1->Cells[i+1][2]);
}
//———————END———————-

//—————построение точек—————-
glPointSize (3);
glBegin(GL_POINTS);
glColor3f (1.0, 0.0, 0);
for(i=0;i<10;i++) { glVertex4f(spine[i][0],spine[i][1],spine[i][2],m); glVertex4f(spine[i][0],spine[i][1],spine[i][2],m); } glColor3f (0.0, 1.0, 0.0); for(i=0;i<11;i++) { glVertex4f(guide[i][0],guide[i][1],guide[i][2],m); glVertex4f(guide[i][0],guide[i][1],guide[i][2],m); } glColor3f (0.0, 0.0, 1.0); for(i=0;i<12;i++) { glVertex4f(link[i][0],link[i][1],link[i][2],m); glVertex4f(link[i][0],link[i][1],link[i][2],m); } glEnd(); //---------------------END---------------------- int h=300; double t=0,rx1, ry1, rx2, ry2, rz1,tempx1, tempy1, tempx2, tempy2,tempz1,tempz2, rz2; //------------кривая ссылки (Безье 3ей степени)---------------------- glColor3f (0.0, 0.0, 1.0); glBegin(GL_LINES); i=0; tempx1=link[0][0]; tempy1=link[0][1]; tempz1=link[0][2]; tempx2=(link[i+2][0]+link[i+4][0])*0.5; tempy2=(link[i+2][1]+link[i+4][1])*0.5; tempz2=(link[i+2][2]+link[i+4][2])*0.5; for(j=0;j 0)
{
koleso=koleso-0.05;
m=m+0.1;
}
}
//—————————————————————————

#ifndef Unit2H
#define Unit2H
//—————————————————————————
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define GL_PI 3.1415f
static GLfloat xRot = 22.0f;
static GLfloat yRot = 11.0f;
static GLfloat split = 4;

//—————————————————————————
class TForm2 : public TForm
{
__published: // IDE-managed Components
TButton *Button1;
void __fastcall FormCreate(TObject *Sender);
void __fastcall Button1Click(TObject *Sender);
void __fastcall FormResize(TObject *Sender);
void __fastcall FormMouseUp(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseDown(TObject *Sender, TMouseButton Button,
TShiftState Shift, int X, int Y);
void __fastcall FormMouseMove(TObject *Sender, TShiftState Shift,
int X, int Y);
void __fastcall FormMouseWheelUp(TObject *Sender,
TShiftState Shift, TPoint &MousePos, bool &Handled);
void __fastcall FormMouseWheelDown(TObject *Sender,
TShiftState Shift, TPoint &MousePos, bool &Handled);

private: // User declarations
HDC hDC;
HGLRC hRC;
public: // User declarations
__fastcall TForm2(TComponent* Owner);
float k,m_y,m_x,l,koleso;
bool Flag_mouse;
GLfloat m;
void __fastcall IdleLoop(TObject*, bool&);
bool OpenGLInit(void);
void SetGLPixelFormat(HDC dhc);
void SetViewport(bool Perspective);
void RenderScene();
void Circle(int r, int x, int y, int z, double a, double b, double c);
};
//—————————————————————————
extern PACKAGE TForm2 *Form2;
//—————————————————————————
#endif


Комментарии запрещены.





Статистика

Рейтинг@Mail.ru