2 * moon-curves.c: A set of primitives + alghos for solving Y at X problmem
3 * for cubic curves. This is used ONLY for KeySpline animation,
4 * not used in any way for drawing.
7 * Michael Dominic K. <mdk@mdk.am>
9 * Copyright 2007 Novell, Inc. (http://www.novell.com)
11 * See the LICENSE file included with the distribution for details.
15 #include "moon-curves.h"
18 point_half_lerp (moon_point
*dest
, moon_point a
, moon_point b
)
20 dest
->x
= a
.x
+ (b
.x
- a
.x
) * 0.5;
21 dest
->y
= a
.y
+ (b
.y
- a
.y
) * 0.5;
25 moon_quadratic_from_cubic (moon_quadratic
*dest
, moon_cubic
*src
)
27 dest
->c0
.x
= src
->c0
.x
; dest
->c0
.y
= src
->c0
.y
;
29 dest
->c1
.x
= (src
->c1
.x
+ src
->c2
.x
) / 2.0;
30 dest
->c1
.y
= (src
->c1
.y
+ src
->c2
.y
) / 2.0;
32 dest
->c2
.x
= src
->c3
.x
; dest
->c2
.y
= src
->c3
.y
;
36 moon_quadratic_y_for_x (double x
, moon_quadratic
*src
)
38 double l
= src
->c2
.x
- src
->c0
.x
;
42 x
= (x
- src
->c0
.x
) / l
;
43 return ((1 - x
) * (1 - x
)) * src
->c0
.y
+ ((2 * x
) * (1 - x
) * src
->c1
.y
) + ((x
* x
) * src
->c2
.y
);
48 moon_quadratic_array_y_for_x (moon_quadratic
*qarr
, double x
, int count
)
52 for (i
= 0; i
< count
; i
++) {
53 if (x
< qarr
[i
].c2
.x
)
54 return moon_quadratic_y_for_x (x
, &qarr
[i
]);
57 g_warning ("Failed to find a matching quadratic segment for %.5f", x
);
62 moon_convert_cubics_to_quadratics (moon_quadratic
*dest_array
, moon_cubic
*src_array
, int count
)
65 for (i
= 0; i
< count
; i
++)
66 moon_quadratic_from_cubic (&dest_array
[i
], &src_array
[i
]);
70 moon_subdivide_cubic (moon_cubic
*dest1
, moon_cubic
*dest2
, moon_cubic
*src
)
72 moon_point p01
, p012
, p0123
;
73 moon_point p12
, p23
, p123
;
75 point_half_lerp (&p01
, src
->c0
, src
->c1
);
76 point_half_lerp (&p12
, src
->c1
, src
->c2
);
77 point_half_lerp (&p23
, src
->c2
, src
->c3
);
79 point_half_lerp (&p012
, p01
, p12
);
81 point_half_lerp (&p123
, p12
, p23
);
82 point_half_lerp (&p0123
, p012
, p123
);
96 recursive_subdivide_func (moon_cubic
*b
, int lvl
, int current_lvl
, int *current_pos
, moon_cubic
*src
)
99 moon_subdivide_cubic (&b1
, &b2
, src
);
101 if (current_lvl
== lvl
) {
102 b
[*current_pos
] = b1
;
103 b
[*current_pos
+ 1] = b2
;
106 recursive_subdivide_func (b
, lvl
, current_lvl
+ 1, current_pos
, &b1
);
107 recursive_subdivide_func (b
, lvl
, current_lvl
+ 1, current_pos
, &b2
);
112 moon_subdivide_cubic_at_level (moon_cubic
*b
, int lvl
, moon_cubic
*src
)
115 recursive_subdivide_func (b
, lvl
, 1, &pos
, src
);