comparison src/xs_curve.c @ 514:982cec405ef0

Cleaned up the drawing function a bit.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 29 Jan 2007 03:26:05 +0000
parents 54d86ee98b98
children 81481e59e195
comparison
equal deleted inserted replaced
513:e5b302358312 514:982cec405ef0
6 6
7 #include "xs_curve.h" 7 #include "xs_curve.h"
8 #include <gtk/gtkdrawingarea.h> 8 #include <gtk/gtkdrawingarea.h>
9 #include <gtk/gtkmain.h> 9 #include <gtk/gtkmain.h>
10 #include <gtk/gtksignal.h> 10 #include <gtk/gtksignal.h>
11
12
13 #define GET_X(i) curve->ctlpoints[i].x
14 #define GET_Y(i) curve->ctlpoints[i].y
15 11
16 12
17 #define RADIUS 3 /* radius of the control points */ 13 #define RADIUS 3 /* radius of the control points */
18 #define RADIUS2 (RADIUS * 2) 14 #define RADIUS2 (RADIUS * 2)
19 15
24 GDK_POINTER_MOTION_HINT_MASK | \ 20 GDK_POINTER_MOTION_HINT_MASK | \
25 GDK_ENTER_NOTIFY_MASK | \ 21 GDK_ENTER_NOTIFY_MASK | \
26 GDK_BUTTON_PRESS_MASK | \ 22 GDK_BUTTON_PRESS_MASK | \
27 GDK_BUTTON_RELEASE_MASK | \ 23 GDK_BUTTON_RELEASE_MASK | \
28 GDK_BUTTON1_MOTION_MASK) 24 GDK_BUTTON1_MOTION_MASK)
25
26 #define GET_X(i) curve->ctlpoints[i].x
27 #define GET_Y(i) curve->ctlpoints[i].y
28
29 29
30 enum { 30 enum {
31 ARG_0, 31 ARG_0,
32 ARG_CURVE_TYPE, 32 ARG_CURVE_TYPE,
33 ARG_MIN_X, 33 ARG_MIN_X,
180 *b = ((k2 - k1) / dx - 3 * (x1 + x2) * (*a)) / 2; 180 *b = ((k2 - k1) / dx - 3 * (x1 + x2) * (*a)) / 2;
181 *c = k1 - (3 * x1 * (*a) + 2 * (*b)) * x1; 181 *c = k1 - (3 * x1 * (*a) + 2 * (*b)) * x1;
182 *d = y1 - ((x1 * (*a) + (*b)) * x1 + (*c)) * x1; 182 *d = y1 - ((x1 * (*a) + (*b)) * x1 + (*c)) * x1;
183 } 183 }
184 184
185 #define x(val) val->x
186 #define y(val) val->y
187 185
188 static void xs_curve_draw(XSCurve *curve, gint width, gint height) 186 static void xs_curve_draw(XSCurve *curve, gint width, gint height)
189 { 187 {
190 gfloat res = 10.0f; 188 gfloat res = 10.0f;
191 GtkStateType state; 189 GtkStateType state;
231 229
232 /* Draw each curve segment */ 230 /* Draw each curve segment */
233 fprintf(stderr, "npoints = %d\n", curve->num_ctlpoints); 231 fprintf(stderr, "npoints = %d\n", curve->num_ctlpoints);
234 for (i = 0; i < curve->num_ctlpoints; i++, ++p0, ++p1, ++p2, ++p3) { 232 for (i = 0; i < curve->num_ctlpoints; i++, ++p0, ++p1, ++p2, ++p3) {
235 gfloat k1, k2, a, b, c, d, x; 233 gfloat k1, k2, a, b, c, d, x;
236 234
237 /* p1 and p2 equal; single point */ 235 if (p1->x == p2->x)
238 if (x(p1) == x(p2))
239 continue; 236 continue;
240 237
241 /* Both end points repeated; straight line */ 238 if (p0->x == p1->x && p2->x == p3->x) {
242 if (x(p0) == x(p1) && x(p2) == x(p3)) { 239 k1 = k2 = (p2->y - p1->y) / (p2->x - p1->x);
243 k1 = k2 = (y(p2) - y(p1)) / (x(p2) - x(p1)); 240 } else if (p0->x == p1->x) {
244 } 241 k2 = (p3->y - p1->y) / (p3->x - p1->x);
245 /* p0 and p1 equal; use f''(x1) = 0 */ 242 k1 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k2) / 2;
246 else if (x(p0) == x(p1)) { 243 } else if (p2->x == p3->x) {
247 k2 = (y(p3) - y(p1)) / (x(p3) - x(p1)); 244 k1 = (p2->y - p0->y) / (p2->x - p0->x);
248 k1 = (3 * (y(p2) - y(p1)) / (x(p2) - x(p1)) - k2) / 2; 245 k2 = (3 * (p2->y - p1->y) / (p2->x - p1->x) - k1) / 2;
249 } 246 } else {
250 /* p2 and p3 equal; use f''(x2) = 0 */ 247 k1 = (p2->y - p0->y) / (p2->x - p0->x);
251 else if (x(p2) == x(p3)) { 248 k2 = (p3->y - p1->y) / (p3->x - p1->x);
252 k1 = (y(p2) - y(p0)) / (x(p2) - x(p0)); 249 }
253 k2 = (3 * (y(p2) - y(p1)) / (x(p2) - x(p1)) - k1) / 2; 250
254 } 251 xs_cubic_coeff(p1->x, p1->y, p2->x, p2->y, k1, k2, &a, &b, &c, &d);
255 /* Normal curve */ 252 fprintf(stderr, "--seg[%1.3f, %1.3f]=>[%1.3f, %1.3f]--\n", p1->x, p1->y, p2->x, p2->y);
256 else { 253 for (x = p1->x; x <= p2->x; x += res) {
257 k1 = (y(p2) - y(p0)) / (x(p2) - x(p0));
258 k2 = (y(p3) - y(p1)) / (x(p3) - x(p1));
259 }
260
261 xs_cubic_coeff(x(p1), y(p1), x(p2), y(p2), k1, k2, &a, &b, &c, &d);
262
263 fprintf(stderr, "--seg[%1.3f, %1.3f]=>[%1.3f, %1.3f]--\n",
264 x(p1), y(p1), x(p2), y(p2));
265
266 for (x = x(p1); x <= x(p2); x += res) {
267 gfloat y = ((a * x + b) * x + c) * x + d; 254 gfloat y = ((a * x + b) * x + c) * x + d;
268 gint qx, qy; 255 gint qx, qy;
269 qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width); 256 qx = RADIUS + xs_project(x, curve->min_x, curve->max_x, width);
270 qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height); 257 qy = RADIUS + xs_project(y, curve->min_y, curve->max_y, height);
271
272 fprintf(stderr, "[%1.3f, %1.3f] -> %d, %d\n", x, y, qx, qy); 258 fprintf(stderr, "[%1.3f, %1.3f] -> %d, %d\n", x, y, qx, qy);
273
274 gdk_draw_point(curve->pixmap, style->fg_gc[state], 259 gdk_draw_point(curve->pixmap, style->fg_gc[state],
275 RADIUS + xs_project(x, curve->min_x, curve->max_x, width), 260 RADIUS + xs_project(x, curve->min_x, curve->max_x, width),
276 RADIUS + xs_project(y, curve->min_y, curve->max_y, height) 261 RADIUS + xs_project(y, curve->min_y, curve->max_y, height));
277 ); 262
278 263 }
279 }
280
281 fprintf(stderr, "-------\n"); 264 fprintf(stderr, "-------\n");
282 } 265 }
283 266
284 /* Draw control points */ 267 /* Draw control points */
285 for (i = 0; i < curve->num_ctlpoints; ++i) { 268 for (i = 0; i < curve->num_ctlpoints; ++i) {
301 style->fg_gc[state], curve->pixmap, 284 style->fg_gc[state], curve->pixmap,
302 0, 0, 0, 0, 285 0, 0, 0, 0,
303 width + RADIUS2, 286 width + RADIUS2,
304 height + RADIUS2); 287 height + RADIUS2);
305 } 288 }
306
307 #undef x
308 #undef y
309 289
310 290
311 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve) 291 static gint xs_curve_graph_events(GtkWidget *widget, GdkEvent *event, XSCurve *curve)
312 { 292 {
313 GdkCursorType new_type = curve->cursor_type; 293 GdkCursorType new_type = curve->cursor_type;