fork download
  1. // TBezierInterpolation.c
  2. #include <stdio.h>
  3. #include <math.h>
  4. #include <stdlib.h>
  5. #include <stdbool.h>
  6. #include <float.h>
  7.  
  8. #define RESOLUTION 32
  9. #define POINTS_LEN 10
  10.  
  11. typedef struct
  12. {
  13. double x, y;
  14. }Point2D;
  15.  
  16.  
  17. Point2D Point2DAdd( Point2D *left, Point2D *right)
  18. {
  19. Point2D newPoint = {left->x + right->x, left->y + right->y};
  20. return newPoint;
  21. }
  22. Point2D Point2DSubtract( Point2D *left, Point2D *right)
  23. {
  24. Point2D newPoint = {left->x - right->x, left->y - right->y};
  25. return newPoint;
  26. }
  27. Point2D Point2DMultiply( Point2D *left, double v)
  28. {
  29. Point2D newPoint = {left->x * v, left->y * v};
  30. return newPoint;
  31. }
  32.  
  33.  
  34. void Point2DNormalize(Point2D *point)
  35. {
  36. double l = sqrt(point->x * point->x + point->y * point->y);
  37. point->x /= l;
  38. point->y /= l;
  39. }
  40.  
  41.  
  42. typedef struct
  43. {
  44. Point2D points[4];
  45. }Segment;
  46.  
  47. void SegmentCalc(Segment *seg,double t, Point2D *p)
  48. {
  49. double t2 = t * t;
  50. double t3 = t2 * t;
  51. double nt = 1.0 - t;
  52. double nt2 = nt * nt;
  53. double nt3 = nt2 * nt;
  54. p->x = nt3 * seg->points[0].x + 3.0 * t * nt2 * seg->points[1].x + 3.0 * t2 * nt * seg->points[2].x + t3 * seg->points[3].x;
  55. p->y = nt3 * seg->points[0].y + 3.0 * t * nt2 * seg->points[1].y + 3.0 * t2 * nt * seg->points[2].y + t3 * seg->points[3].y;
  56. }
  57.  
  58.  
  59. bool CalculateSpline( Point2D values[], int valuesSize, Segment bezier[])
  60. {
  61. int n = valuesSize - 1;
  62.  
  63. if (valuesSize < 2)
  64. return false;
  65.  
  66. Point2D tgL= {0.0,0.0};
  67. Point2D tgR= {0.0,0.0};
  68. Point2D cur= {0.0,0.0};
  69. Point2D next = Point2DSubtract(&values[1] ,&values[0]);
  70. Point2D tmpPoint= {0.0,0.0};
  71. Point2DNormalize(&next);
  72.  
  73. double l1 = 0.0, l2= 0.0, tmp= 0.0, x= 0.0;
  74.  
  75. --n;
  76.  
  77. for (int i = 0; i < n; ++i)
  78. {
  79. bezier[i].points[0] = bezier[i].points[1] = values[i];
  80. bezier[i].points[2] = bezier[i].points[3] = values[i + 1];
  81.  
  82. cur = next;
  83. next = Point2DSubtract(&values[i + 2],&values[i + 1]);
  84. Point2DNormalize(&next);
  85.  
  86. tgL = tgR;
  87.  
  88. tgR = Point2DAdd(&cur,&next);
  89. Point2DNormalize(&tgR);
  90.  
  91. if (abs(values[i + 1].y - values[i].y) < DBL_EPSILON)
  92. {
  93. l1 = l2 = 0.0;
  94. }
  95. else
  96. {
  97. tmp = values[i + 1].x - values[i].x;
  98. l1 = abs(tgL.x) > DBL_EPSILON ? tmp / (2.0 * tgL.x) : 1.0;
  99. l2 = abs(tgR.x) > DBL_EPSILON ? tmp / (2.0 * tgR.x) : 1.0;
  100. }
  101.  
  102. if (abs(tgL.x) > DBL_EPSILON && abs(tgR.x) > DBL_EPSILON)
  103. {
  104. tmp = tgL.y / tgL.x - tgR.y / tgR.x;
  105. if (abs(tmp) > DBL_EPSILON)
  106. {
  107. x = (values[i + 1].y - tgR.y / tgR.x * values[i + 1].x - values[i].y + tgL.y / tgL.x * values[i].x) / tmp;
  108. if (x > values[i].x && x < values[i + 1].x)
  109. {
  110. if (tgL.y > 0.0)
  111. {
  112. if (l1 > l2)
  113. l1 = 0.0;
  114. else
  115. l2 = 0.0;
  116. }
  117. else
  118. {
  119. if (l1 < l2)
  120. l1 = 0.0;
  121. else
  122. l2 = 0.0;
  123. }
  124. }
  125. }
  126. }
  127. tmpPoint = Point2DMultiply(&tgL , l1);
  128. bezier[i].points[1] = Point2DAdd(& bezier[i].points[1],&tmpPoint);
  129. tmpPoint = Point2DMultiply(&tgR , l2);
  130. bezier[i].points[2] = Point2DSubtract(& bezier[i].points[2],&tmpPoint);
  131. }
  132.  
  133. l1 = abs(tgL.x) > DBL_EPSILON ? (values[n + 1].x - values[n].x) / (2.0 * tgL.x) : 1.0;
  134.  
  135. bezier[n].points[0] = bezier[n].points[1] = values[n];
  136. bezier[n].points[2] = bezier[n].points[3] = values[n + 1];
  137. tmpPoint = Point2DMultiply(&tgR , l1);
  138. bezier[n].points[1] = Point2DAdd(& bezier[n].points[1],&tmpPoint);
  139.  
  140. return true;
  141. }
  142.  
  143. int main()
  144. {
  145.  
  146. Point2D testValues[POINTS_LEN] = {{0.0, 0.0},
  147. {20.0, 0.0},
  148. {45.0, -47.0},
  149. {53.0, 335.0},
  150. {57.0, 26.0},
  151. {62.0, 387.0},
  152. { 74.0, 104.0},
  153. { 89.0, 0.0},
  154. {95.0, 100.0},
  155. { 100.0, 0.0} };
  156. Segment spline[100];
  157.  
  158. Point2D p = {0.0,0.0};
  159.  
  160.  
  161. CalculateSpline(testValues,POINTS_LEN, spline);
  162.  
  163. for(int i = 0; i < POINTS_LEN - 1;i++)
  164. {
  165. for (int j = 0; j < RESOLUTION; j++)
  166. {
  167. SegmentCalc(&spline[i],(double)j / (double)RESOLUTION, &p);
  168. printf("%lf %lf\n", p.x, p.y);
  169. }
  170. }
  171.  
  172. printf("%lf %lf\n", testValues[POINTS_LEN - 1].x,testValues[POINTS_LEN - 1].y);
  173.  
  174. return 0;
  175. }
  176.  
Success #stdin #stdout 0s 10320KB
stdin
Standard input is empty
stdout
0.000000 0.000000
0.057373 0.000000
0.224609 0.000000
0.494385 0.000000
0.859375 0.000000
1.312256 0.000000
1.845703 0.000000
2.452393 0.000000
3.125000 0.000000
3.856201 0.000000
4.638672 0.000000
5.465088 0.000000
6.328125 0.000000
7.220459 0.000000
8.134766 0.000000
9.063721 0.000000
10.000000 0.000000
10.936279 0.000000
11.865234 0.000000
12.779541 0.000000
13.671875 0.000000
14.534912 0.000000
15.361328 0.000000
16.143799 0.000000
16.875000 0.000000
17.547607 0.000000
18.154297 0.000000
18.687744 0.000000
19.140625 0.000000
19.505615 0.000000
19.775391 0.000000
19.942627 0.000000
20.000000 0.000000
20.144375 -0.180793
20.411338 -0.615243
20.792741 -1.286295
21.280433 -2.176892
21.866264 -3.269978
22.542084 -4.548496
23.299743 -5.995390
24.131091 -7.593604
25.027978 -9.326080
25.982253 -11.175764
26.985768 -13.125597
28.030371 -15.158525
29.107912 -17.257491
30.210243 -19.405437
31.329212 -21.585309
32.456669 -23.780049
33.584466 -25.972601
34.704450 -28.145909
35.808473 -30.282916
36.888385 -32.366567
37.936034 -34.379804
38.943272 -36.305571
39.901949 -38.126812
40.803913 -39.826470
41.641016 -41.387489
42.405107 -42.792814
43.088036 -44.025386
43.681653 -45.068151
44.177808 -45.904051
44.568350 -46.516030
44.845131 -46.887032
45.000000 -47.000000
45.105696 -45.883767
45.239163 -42.671713
45.398554 -37.503606
45.582022 -30.519214
45.787723 -21.858303
46.013810 -11.660641
46.258437 -0.065996
46.519758 12.785865
46.795927 26.755174
47.085098 41.702165
47.385425 57.487069
47.695061 73.970119
48.012162 91.011548
48.334880 108.471589
48.661371 126.210473
48.989787 144.088435
49.318283 161.965705
49.645012 179.702517
49.968130 197.159103
50.285789 214.195696
50.596144 230.672528
50.897348 246.449832
51.187557 261.387841
51.464922 275.346787
51.727600 288.186903
51.973743 299.768421
52.201505 309.951574
52.409041 318.596594
52.594505 325.563714
52.756050 330.713167
52.891830 333.905184
53.000000 335.000000
53.096618 334.113236
53.198729 331.529131
53.305967 327.360843
53.417966 321.721527
53.534360 314.724341
53.654782 306.482441
53.778866 297.108984
53.906247 286.717127
54.036557 275.420027
54.169430 263.330839
54.304501 250.562722
54.441403 237.228831
54.579770 223.442324
54.719235 209.316357
54.859433 194.964087
54.999997 180.498671
55.140561 166.033265
55.280759 151.681026
55.420225 137.555111
55.558592 123.768676
55.695494 110.434879
55.830565 97.666876
55.963439 85.577824
56.093749 74.280879
56.221130 63.889198
56.345214 54.515939
56.465637 46.274257
56.582031 39.277310
56.694031 33.638254
56.801269 29.470246
56.903381 26.886442
57.000000 26.000000
57.099488 27.035503
57.209962 30.053968
57.330691 34.923200
57.460942 41.511004
57.599982 49.685186
57.747079 59.313551
57.901501 70.263905
58.062514 82.404053
58.229387 95.601801
58.401388 109.724954
58.577782 124.641317
58.757839 140.218696
58.940826 156.324897
59.126009 172.827724
59.312658 189.594984
59.500038 206.494481
59.687418 223.394022
59.874066 240.161411
60.059248 256.664454
60.242232 272.770956
60.422286 288.348724
60.598678 303.265561
60.770674 317.389274
60.937543 330.587669
61.098551 342.728550
61.252967 353.679723
61.400058 363.308994
61.539092 371.484168
61.669335 378.073049
61.790056 382.943445
61.900522 385.963160
62.000000 387.000000
62.122134 386.192252
62.298526 383.835067
62.525380 380.031543
62.798904 374.884778
63.115302 368.497872
63.470780 360.973922
63.861544 352.416028
64.283799 342.927287
64.733752 332.610799
65.207607 321.569662
65.701570 309.906975
66.211847 297.725836
66.734644 285.129344
67.266166 272.220598
67.802619 259.102695
68.340208 245.878735
68.875139 232.651816
69.403619 219.525037
69.921851 206.601496
70.426043 193.984291
70.912399 181.776523
71.377126 170.081288
71.816428 159.001686
72.226513 148.640815
72.603584 139.101774
72.943848 130.487661
73.243511 122.901575
73.498778 116.446615
73.705855 111.225879
73.860947 107.342465
73.960260 104.899473
74.000000 104.000000
74.048348 103.613938
74.172753 102.667488
74.368321 101.198211
74.630160 99.243668
74.953375 96.841422
75.333073 94.029035
75.764361 90.844069
76.242345 87.324084
76.762132 83.506644
77.318829 79.429310
77.907542 75.129644
78.523378 70.645207
79.161443 66.013563
79.816844 61.272271
80.484687 56.458896
81.160079 51.610997
81.838127 46.766137
82.513937 41.961879
83.182616 37.235783
83.839271 32.625412
84.479007 28.168327
85.096932 23.902091
85.688152 19.864265
86.247774 16.092411
86.770904 12.624091
87.252649 9.496867
87.688115 6.748301
88.072410 4.415954
88.400639 2.537389
88.667909 1.150167
88.869327 0.291850
89.000000 0.000000
89.102280 0.290543
89.221049 1.129965
89.355208 2.481662
89.503658 4.309036
89.665300 6.575485
89.839034 9.244407
90.023763 12.279203
90.218386 15.643270
90.421804 19.300009
90.632919 23.212817
90.850631 27.345095
91.073841 31.660241
91.301450 36.121654
91.532359 40.692733
91.765468 45.336877
91.999679 50.017486
92.233893 54.697959
92.467010 59.341693
92.697931 63.912090
92.925558 68.372546
93.148791 72.686463
93.366530 76.817238
93.577677 80.728270
93.781133 84.382959
93.975799 87.744704
94.160575 90.776904
94.334362 93.442958
94.496062 95.706264
94.644574 97.530223
94.778801 98.878232
94.897643 99.713692
95.000000 100.000000
95.102324 99.712696
95.220945 98.876132
95.354581 97.526925
95.501950 95.701694
95.661770 93.437057
95.832759 90.769633
96.013636 87.736040
96.203120 84.372897
96.399927 80.716821
96.602778 76.804432
96.810389 72.672347
97.021479 68.357184
97.234766 63.895563
97.448969 59.324102
97.662806 54.679418
97.874995 49.998131
98.084255 45.316858
98.289303 40.672218
98.488857 36.100829
98.681637 31.639311
98.866361 27.324280
99.041746 23.192355
99.206510 19.280156
99.359373 15.624299
99.499053 12.261404
99.624267 9.228088
99.733733 6.560971
99.826171 4.296671
99.900299 2.471805
99.954834 1.122992
99.988495 0.286851
100.000000 0.000000