-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbezier_curve.h
219 lines (198 loc) · 6.3 KB
/
bezier_curve.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
#pragma once
//使用glmap
#include <stdlib.h>
#include <time.h>
#include <GL/freeglut.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <GL/freeglut_ext.h>
#include <iomanip>
#include <string>
#include <cassert>
#include <vector>
using namespace std;
GLfloat cur1[4][3];
bool mouseLeftDown1;
bool mouseRightDown1;
bool mouseMiddleDown1;
float mouseX1, mouseY1;
float cameraDistanceX1;
float cameraDistanceY1;
float cameraAngleX1;
float cameraAngleY1;
float times1;
class Bezier_curve {
public:
Bezier_curve(const char* datafile) {
ifstream is(datafile);
int row = 0;
string line;
while (std::getline(is, line))
{
line_process(line);//把行首和行尾的多个空格, tab去掉,把注释文字也去掉
if (line.empty()) continue;//line为空则继续
//根据实际需求处理
std::istringstream iss(line);
double x_temp, y_temp, z_temp;
iss >> x_temp >> y_temp >> z_temp;
cur1[row][0] = x_temp;
cur1[row][1] = y_temp;
cur1[row][2] = z_temp;
row++;
}
}
void init(void)
{
glClearColor(0.0, 0.0, 0.0, 1.0);
glMap1f(GL_MAP1_VERTEX_3, 0, 100, 3, 4, &cur1[0][0]); // 读取文件中的控制点坐标,shape = (4, 3)
glEnable(GL_MAP1_VERTEX_3);
//反走样
glEnable(GL_BLEND);
glEnable(GL_LINE_SMOOTH);
glHint(GL_LINE_SMOOTH_HINT, GL_FASTEST);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
static void ControlPoint()//画点
{
glPointSize(5);
glBegin(GL_POINTS);
for (unsigned int i = 0; i < 4; i++) {
glVertex3fv(cur1[i]);
}
glEnd();
}
static void display(void)
{
glRotatef(cameraAngleX1, 1, 0, 0);
glRotatef(cameraAngleY1, 0, 1, 0);
glTranslatef(cameraDistanceX1, cameraDistanceY1, 0);
glScalef(times1, times1, times1);//缩放
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glColor3f(1.0, 0.0, 0.0);
ControlPoint();
glColor3f(0.0, 1.0, 0.0);
glMapGrid1f(100, 0.0f, 100.0f);
glEvalMesh1(GL_LINE, 0, 100);
glutSwapBuffers();
}
static void reshape(GLsizei w, GLsizei h)
{
glViewport(0, 0, w, h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if (w <= h)
glOrtho(-5.0, 5.0, -5.0 * (GLfloat)h / (GLfloat)w, 5.0 * (GLfloat)h / (GLfloat)w, -5.0, 5.0);
else
glOrtho(-5.0 * (GLfloat)w / (GLfloat)h, 5.0 * (GLfloat)w / (GLfloat)h, -5.0, 5.0, -5.0, 5.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}
static void keyboard(unsigned char key, int x, int y)
{
switch (key)
{
case 27: //ESC键
exit(0);
break;
default:
break;
}
}
static void mouseCB(int button, int state, int x, int y)
{
mouseX1 = x;
mouseY1 = y;
times1 = 1;
if (button == GLUT_LEFT_BUTTON)
{
if (state == GLUT_DOWN)
{
mouseLeftDown1 = true;
}
else if (state == GLUT_UP)
mouseLeftDown1 = false;
}
else if (button == GLUT_RIGHT_BUTTON)
{
if (state == GLUT_DOWN)
{
mouseRightDown1 = true;
}
else if (state == GLUT_UP)
mouseRightDown1 = false;
}
}
static void mouseMotionCB(int x, int y)
{
cameraAngleX1 = cameraAngleY1 = 0;
cameraDistanceX1 = cameraDistanceY1 = 0;
if (mouseLeftDown1)
{
cameraAngleY1 += (x - mouseX1) * 0.001f;
cameraAngleX1 += (y - mouseY1) * 0.001f;
mouseX1 = x;
mouseY1 = y;
}
if (mouseRightDown1)
{
cameraDistanceX1 = (x - mouseX1) * 0.001f;
cameraDistanceY1 = -(y - mouseY1) * 0.001f;
mouseY1 = y;
mouseX1 = x;
}
glutPostRedisplay();
}
static void mouseWheel(int button, int state, int x, int y)
{
if (button == 0 && state == GLUT_UP) // 往上滚滚轮,放大
{
times1 = 1 + 0.00008f;
glutPostRedisplay();
}
else { // 往下滚滚轮,缩小
times1 = 1 - 0.00008f;
glutPostRedisplay();
}
}
void render()
{
int a = 1;
glutInit(&a, NULL);
srand((unsigned int)time(0));
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);//使用双缓存模式和深度缓存
glutInitWindowPosition(0, 0);
glutInitWindowSize(800, 800);
glutCreateWindow("Bezier曲线线框模型");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutKeyboardFunc(keyboard);
glutIdleFunc(display);//设置空闲时调用的函数
glutMouseFunc(mouseCB);
glutMotionFunc(mouseMotionCB);
glutMouseWheelFunc(mouseWheel);
glutMainLoop();
}
void line_process(std::string& line, const std::string comment_str = "#")
{
for (char& c : line)//C++11以上版本的语法
{
//制表符 tab,逗号,分号都当作有效的分隔符,统一转成空格
//为了避免错误,回车符和换行符也转为空格(否则无法处理空行)
if (c == '\t' || c == ',' || c == ';' || c == '\r' || c == '\n')
c = ' ';
}
line.erase(0, line.find_first_not_of(" "));//删除行首空格
line.erase(line.find_last_not_of(" ") + 1);//删除行末空格
//调用的string& erase (size_t pos = 0, size_t len = npos);
//len为默认参数
//查找注释符所在位置,如果不存在,则得到string::npos
int n_comment_start = line.find_first_of(comment_str);
if (n_comment_start != std::string::npos)//这一句必须的
line.erase(n_comment_start); //删除注释
//处理完毕。如果这一行只有空格,制表符 tab,注释,那么处理后line为空;
//如果行首有多个空格(或者空格和tab交错),行尾为注释,那么处理后字符串line的
//行首多个空格(和tab)和行尾注释被删掉,只保留有意义的内容。
}
};