SHOW:
|
|
- or go back to the newest paste.
1 | #include <math.h> | |
2 | #include <stdlib.h> | |
3 | ||
4 | #if defined(__APPLE__) | |
5 | #include <OpenGL/gl.h> | |
6 | #include <OpenGL/glu.h> | |
7 | #include <GLUT/glut.h> | |
8 | #else | |
9 | #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) | |
10 | #include <windows.h> | |
11 | #endif | |
12 | #include <GL/gl.h> | |
13 | #include <GL/glu.h> | |
14 | #include <GL/glut.h> | |
15 | #endif | |
16 | ||
17 | struct Vector { | |
18 | float x, y, z; | |
19 | ||
20 | Vector(float v = 0) : x(v), y(v), z(v) { } | |
21 | Vector(float x, float y, float z) : x(x), y(y), z(z) { } | |
22 | Vector operator+(const Vector& v) const { return Vector(x + v.x, y + v.y, z + v.z); } | |
23 | Vector operator-(const Vector& v) const { return Vector(x - v.x, y - v.y, z - v.z); } | |
24 | Vector& operator+=(const Vector& v) { x += v.x, y += v.y, z += v.z; return *this; } | |
25 | Vector operator*(const Vector& v) const { return Vector(x * v.x, y * v.y, z * v.z); } | |
26 | Vector operator/(const Vector& v) const { return Vector(x / v.x, y / v.y, z / v.z); } | |
27 | }; | |
28 | ||
29 | Vector operator*(float f, const Vector& v) { | |
30 | return v*f; | |
31 | } | |
32 | ||
33 | struct Curve { | |
34 | Vector color; | |
35 | size_t num_cpts; | |
36 | static const size_t max_cpt_num = 50; | |
37 | Vector cpts[max_cpt_num]; // controll_points | |
38 | ||
39 | Curve(const Vector& color) : color(color), num_cpts(0) { } | |
40 | virtual ~Curve() { } | |
41 | ||
42 | // Az x, y koordináták tárolják a pont helyét, míg a 'z' a görbe paramétert | |
43 | void AddContollPoint(const Vector& v) { | |
44 | cpts[num_cpts++] = v; | |
45 | } | |
46 | ||
47 | void AddContollPoint(float x, float y, float z) { | |
48 | cpts[num_cpts++] = Vector(x, y, z); | |
49 | } | |
50 | ||
51 | virtual Vector r(float t) const = 0; | |
52 | const Vector& p(int i) const { return cpts[i]; } | |
53 | float t(int i) const { return cpts[i].z - cpts[0].z; } | |
54 | ||
55 | void DrawCurve(float time) const { | |
56 | const float resolution = (t(num_cpts - 1) - t(0)) / 200; | |
57 | glBegin(GL_LINE_STRIP); { | |
58 | glColor3fv(&color.x); | |
59 | for(float i = t(0); i <= t(num_cpts - 1); i += resolution) { | |
60 | if(time < p(0).z + i) | |
61 | break; | |
62 | Vector v = r(i); | |
63 | glVertex2f(v.x, v.y); | |
64 | } | |
65 | } glEnd(); | |
66 | } | |
67 | }; | |
68 | ||
69 | // Tenziós Catmull-Rom | |
70 | struct TCR : public Curve { | |
71 | float tension; | |
72 | ||
73 | TCR(const Vector& color = Vector(1, 1, 1), float tension = -0.5f) | |
74 | : Curve(color), tension(tension) | |
75 | { } | |
76 | ||
77 | Vector v(int i) const { | |
78 | if(i == 0 || i == num_cpts - 1) { | |
79 | return 0.0f; // Itt nullával osztanánk, ha az alsó képletet használnánk. | |
80 | } else { | |
81 | // TCR definíció szerinti sebesség képlete. | |
82 | Vector prev = (p(i) - p(i-1)) / (t(i) - t(i-1)); | |
83 | Vector next = (p(i+1) - p(i)) / (t(i+1) - t(i)); | |
84 | return 0.5f * (prev + next) * (1 - tension); | |
85 | } | |
86 | } | |
87 | ||
88 | // Visszaadja, hogy a paraméterben kapott értéknél kisebb | |
89 | // görbeparaméterű pontok közül, az adott értékhez a legközlebbit. | |
90 | int SearchIndex(float curr_t) const { | |
91 | for(int i = 0; i + 1 < num_cpts; ++i) { | |
92 | if(t(i+1) > curr_t) { | |
93 | return i; | |
94 | } | |
95 | } | |
96 | return num_cpts - 1; | |
97 | } | |
98 | ||
99 | // Cattmull-Rom képletébe behelyettesítés | |
100 | Vector r(float curr_t) const { | |
101 | int i = SearchIndex(curr_t); | |
102 | if(i == num_cpts - 1) { | |
103 | return p(i); | |
104 | } | |
105 | ||
106 | Vector a[4]; | |
107 | a[0] = p(i); | |
108 | a[1] = v(i); | |
109 | a[2] = 3*(p(i+1) - p(i)) / pow(t(i+1) - t(i), 2) - | |
110 | (v(i+1) + 2*v(i)) / (t(i+1) - t(i)); | |
111 | a[3] = 2*(p(i) - p(i+1)) / pow(t(i+1) - t(i), 3) + | |
112 | (v(i+1) + v(i)) / pow(t(i+1) - t(i), 2); | |
113 | ||
114 | Vector ret; | |
115 | for(int j = 0; j < 4; ++j) { | |
116 | ret += pow(curr_t - t(i), j) * a[j]; | |
117 | } | |
118 | ||
119 | return ret; | |
120 | } | |
121 | }; | |
122 | ||
123 | TCR tcr_s = TCR(Vector(0, 0, 0)); | |
124 | TCR tcr_or = TCR(Vector(0, 0, 0)); | |
125 | TCR tcr_left_dot = TCR(Vector(0, 0, 0)); | |
126 | TCR tcr_right_dot = TCR(Vector(0, 0, 0)); | |
127 | ||
128 | void onInitialization() { | |
129 | glClearColor(1, 1, 1, 1); | |
130 | ||
131 | glLineWidth(3.0f); | |
132 | ||
133 | tcr_s.AddContollPoint(-0.5f, 0.8f, 0.0f); | |
134 | tcr_s.AddContollPoint(-0.9f, 0.4f, 0.33f); | |
135 | tcr_s.AddContollPoint(-0.5f, -0.4f, 0.66f); | |
136 | tcr_s.AddContollPoint(-0.9f, -0.8f, 1.0f); | |
137 | ||
138 | tcr_or.AddContollPoint(-0.61f, -0.1f, 1.10f); | |
139 | tcr_or.AddContollPoint(-0.3f, 0.0f, 1.20f); | |
140 | tcr_or.AddContollPoint(0.0f, 0.15f, 1.25f); | |
141 | tcr_or.AddContollPoint(0.3f, 0.00f, 1.30f); | |
142 | tcr_or.AddContollPoint(0.3f, -0.4f, 1.40f); | |
143 | tcr_or.AddContollPoint(-0.3f, -0.4f, 1.50f); | |
144 | tcr_or.AddContollPoint(-0.3f, 0.0f, 1.60f); | |
145 | tcr_or.AddContollPoint(0.6f, 0.15f, 1.75f); | |
146 | tcr_or.AddContollPoint(0.6f, -0.4f, 1.90f); | |
147 | tcr_or.AddContollPoint(0.71f, -0.1f, 1.975f); | |
148 | tcr_or.AddContollPoint(0.8f, 0.15f, 2.05f); | |
149 | tcr_or.AddContollPoint(1.0f, 0.15f, 2.1f); | |
150 | ||
151 | tcr_left_dot.AddContollPoint(-0.20f, 0.42f, 2.2f); | |
152 | tcr_left_dot.AddContollPoint(-0.22f, 0.40f, 2.22f); | |
153 | tcr_left_dot.AddContollPoint(-0.20f, 0.38f, 2.24f); | |
154 | tcr_left_dot.AddContollPoint(-0.18f, 0.40f, 2.26f); | |
155 | tcr_left_dot.AddContollPoint(-0.20f, 0.42f, 2.28f); | |
156 | ||
157 | tcr_right_dot.AddContollPoint(0.20f, 0.42f, 2.3f); | |
158 | tcr_right_dot.AddContollPoint(0.22f, 0.40f, 2.32f); | |
159 | tcr_right_dot.AddContollPoint(0.20f, 0.38f, 2.34f); | |
160 | tcr_right_dot.AddContollPoint(0.18f, 0.40f, 2.36f); | |
161 | tcr_right_dot.AddContollPoint(0.20f, 0.42f, 2.38f); | |
162 | } | |
163 | ||
164 | void onDisplay() { | |
165 | glClear(GL_COLOR_BUFFER_BIT); | |
166 | ||
167 | float time = glutGet(GLUT_ELAPSED_TIME) / 2000.0f; | |
168 | ||
169 | tcr_s.DrawCurve(time); | |
170 | tcr_or.DrawCurve(time); | |
171 | tcr_left_dot.DrawCurve(time); | |
172 | tcr_right_dot.DrawCurve(time); | |
173 | ||
174 | glutSwapBuffers(); | |
175 | } | |
176 | ||
177 | void onIdle() { | |
178 | glutPostRedisplay(); | |
179 | } | |
180 | ||
181 | void onKeyboard(unsigned char key, int, int) {} | |
182 | ||
183 | void onKeyboardUp(unsigned char key, int, int) {} | |
184 | ||
185 | void onMouse(int, int, int, int) {} | |
186 | ||
187 | void onMouseMotion(int, int) {} | |
188 | ||
189 | int main(int argc, char **argv) { | |
190 | glutInit(&argc, argv); | |
191 | - | glutInitWindowSize(300, 300); |
191 | + | glutInitWindowSize(600, 600); |
192 | - | glutInitWindowPosition(0, 0); |
192 | + | glutInitWindowPosition(100, 100); |
193 | glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); | |
194 | ||
195 | glutCreateWindow("Grafika pelda program"); | |
196 | ||
197 | glMatrixMode(GL_MODELVIEW); | |
198 | glLoadIdentity(); | |
199 | glMatrixMode(GL_PROJECTION); | |
200 | glLoadIdentity(); | |
201 | ||
202 | onInitialization(); | |
203 | ||
204 | glutDisplayFunc(onDisplay); | |
205 | glutMouseFunc(onMouse); | |
206 | glutIdleFunc(onIdle); | |
207 | glutKeyboardFunc(onKeyboard); | |
208 | glutKeyboardUpFunc(onKeyboardUp); | |
209 | glutMotionFunc(onMouseMotion); | |
210 | ||
211 | glutMainLoop(); | |
212 | ||
213 | return 0; | |
214 | } |