fork(2) download
  1.  
  2.  
  3. // TBezierInterpolation.cpp
  4. #include <vector>
  5. #include <iostream>
  6. #include <cmath>
  7.  
  8. using namespace std;
  9.  
  10. #define EPSILON 1.0e-5
  11. #define RESOLUTION 32
  12.  
  13. class Point2D
  14. {
  15. public:
  16. double x, y;
  17.  
  18. Point2D() { x = y = 0.0; };
  19. Point2D(double _x, double _y) { x = _x; y = _y; };
  20.  
  21. Point2D operator +(const Point2D &point) const { return Point2D(x + point.x, y + point.y); };
  22. Point2D operator -(const Point2D &point) const { return Point2D(x - point.x, y - point.y); };
  23. Point2D operator *(double v) const { return Point2D(x * v, y * v); };
  24. void operator +=(const Point2D &point) { x += point.x; y += point.y; };
  25. void operator -=(const Point2D &point) { x -= point.x; y -= point.y; };
  26.  
  27. void normalize()
  28. {
  29. double l = sqrt(x * x + y * y);
  30. x /= l;
  31. y /= l;
  32. }
  33. };
  34.  
  35. class Segment
  36. {
  37. public:
  38. Point2D points[4];
  39.  
  40. void calc(double t, Point2D &p)
  41. {
  42. double t2 = t * t;
  43. double t3 = t2 * t;
  44. double nt = 1.0 - t;
  45. double nt2 = nt * nt;
  46. double nt3 = nt2 * nt;
  47. p.x = nt3 * points[0].x + 3.0 * t * nt2 * points[1].x + 3.0 * t2 * nt * points[2].x + t3 * points[3].x;
  48. p.y = nt3 * points[0].y + 3.0 * t * nt2 * points[1].y + 3.0 * t2 * nt * points[2].y + t3 * points[3].y;
  49. };
  50. };
  51.  
  52. bool calculateSpline(const vector<Point2D> &values, vector<Segment> &bezier)
  53. {
  54. int n = values.size() - 1;
  55.  
  56. if (n < 2)
  57. return false;
  58.  
  59. bezier.resize(n);
  60.  
  61. Point2D tgL;
  62. Point2D tgR;
  63. Point2D cur;
  64. Point2D next = values[1] - values[0];
  65. next.normalize();
  66.  
  67. double l1, l2, tmp, x;
  68.  
  69. --n;
  70.  
  71. for (int i = 0; i < n; ++i)
  72. {
  73. bezier[i].points[0] = bezier[i].points[1] = values[i];
  74. bezier[i].points[2] = bezier[i].points[3] = values[i + 1];
  75.  
  76. cur = next;
  77. next = values[i + 2] - values[i + 1];
  78. next.normalize();
  79.  
  80. tgL = tgR;
  81.  
  82. tgR = cur + next;
  83. tgR.normalize();
  84.  
  85. if (abs(values[i + 1].y - values[i].y) < EPSILON)
  86. {
  87. l1 = l2 = 0.0;
  88. }
  89. else
  90. {
  91. tmp = values[i + 1].x - values[i].x;
  92. l1 = abs(tgL.x) > EPSILON ? tmp / (2.0 * tgL.x) : 1.0;
  93. l2 = abs(tgR.x) > EPSILON ? tmp / (2.0 * tgR.x) : 1.0;
  94. }
  95.  
  96. if (abs(tgL.x) > EPSILON && abs(tgR.x) > EPSILON)
  97. {
  98. tmp = tgL.y / tgL.x - tgR.y / tgR.x;
  99. if (abs(tmp) > EPSILON)
  100. {
  101. x = (values[i + 1].y - tgR.y / tgR.x * values[i + 1].x - values[i].y + tgL.y / tgL.x * values[i].x) / tmp;
  102. if (x > values[i].x && x < values[i + 1].x)
  103. {
  104. if (tgL.y > 0.0)
  105. {
  106. if (l1 > l2)
  107. l1 = 0.0;
  108. else
  109. l2 = 0.0;
  110. }
  111. else
  112. {
  113. if (l1 < l2)
  114. l1 = 0.0;
  115. else
  116. l2 = 0.0;
  117. }
  118. }
  119. }
  120. }
  121.  
  122. bezier[i].points[1] += tgL * l1;
  123. bezier[i].points[2] -= tgR * l2;
  124. }
  125.  
  126. l1 = abs(tgL.x) > EPSILON ? (values[n + 1].x - values[n].x) / (2.0 * tgL.x) : 1.0;
  127.  
  128. bezier[n].points[0] = bezier[n].points[1] = values[n];
  129. bezier[n].points[2] = bezier[n].points[3] = values[n + 1];
  130. bezier[n].points[1] += tgR * l1;
  131.  
  132. return true;
  133. }
  134.  
  135. int main()
  136. {
  137. vector<Point2D> testValues;
  138. vector<Segment> spline;
  139. Point2D p;
  140.  
  141. testValues.push_back(Point2D(0, 0));
  142. testValues.push_back(Point2D(20, 0));
  143. testValues.push_back(Point2D(45, -47));
  144. testValues.push_back(Point2D(53, 335));
  145. testValues.push_back(Point2D(57, 26));
  146. testValues.push_back(Point2D(62, 387));
  147. testValues.push_back(Point2D(74, 104));
  148. testValues.push_back(Point2D(89, 0));
  149. testValues.push_back(Point2D(95, 100));
  150. testValues.push_back(Point2D(100, 0));
  151.  
  152. calculateSpline(testValues, spline);
  153.  
  154. for (auto s : spline)
  155. {
  156. for (int i = 0; i < RESOLUTION; ++i)
  157. {
  158. s.calc((double)i / (double)RESOLUTION, p);
  159. cout << p.x << " " << p.y << endl;
  160. }
  161. }
  162.  
  163. cout << testValues.back().x << " " << testValues.back().y << endl;
  164.  
  165. return 0;
  166. }
Success #stdin #stdout 0s 15240KB
stdin
Standard input is empty
stdout
0 0
0.057373 0
0.224609 0
0.494385 0
0.859375 0
1.31226 0
1.8457 0
2.45239 0
3.125 0
3.8562 0
4.63867 0
5.46509 0
6.32812 0
7.22046 0
8.13477 0
9.06372 0
10 0
10.9363 0
11.8652 0
12.7795 0
13.6719 0
14.5349 0
15.3613 0
16.1438 0
16.875 0
17.5476 0
18.1543 0
18.6877 0
19.1406 0
19.5056 0
19.7754 0
19.9426 0
20 0
21.136 -0.803974
22.2034 -1.79807
23.2066 -2.96757
24.1504 -4.29773
25.0392 -5.77386
25.8777 -7.38121
26.6704 -9.10506
27.4219 -10.9307
28.1367 -12.8434
28.8196 -14.8284
29.4749 -16.8711
30.1074 -18.9566
30.7216 -21.0703
31.322 -23.1974
31.9133 -25.3233
32.5 -27.4332
33.0867 -29.5123
33.678 -31.546
34.2784 -33.5195
34.8926 -35.4181
35.5251 -37.227
36.1804 -38.9317
36.8633 -40.5172
37.5781 -41.969
38.3296 -43.2723
39.1223 -44.4123
39.9608 -45.3744
40.8496 -46.1438
41.7934 -46.7057
42.7966 -47.0456
43.864 -47.1486
45 -47
45.3635 -45.8203
45.7051 -42.5527
46.0261 -37.3367
46.3281 -30.3116
46.6125 -21.6168
46.8809 -11.3917
47.1345 0.224322
47.375 13.0919
47.6038 27.0717
47.8223 42.0243
48.032 57.8103
48.2344 74.2903
48.4309 91.3251
48.623 108.775
48.8123 126.501
49 144.363
49.1877 162.223
49.377 179.941
49.5691 197.376
49.7656 214.391
49.968 230.846
50.1777 246.6
50.3962 261.516
50.625 275.453
50.8655 288.273
51.1191 299.835
51.3875 310
51.6719 318.63
51.9739 325.584
52.2949 330.723
52.6365 333.908
53 335
53.1818 334.113
53.3525 331.528
53.5131 327.36
53.6641 321.72
53.8063 314.723
53.9404 306.481
54.0673 297.107
54.1875 286.716
54.3019 275.418
54.4111 263.329
54.516 250.561
54.6172 237.227
54.7155 223.441
54.8115 209.315
54.9061 194.963
55 180.497
55.0939 166.032
55.1885 151.68
55.2845 137.554
55.3828 123.768
55.484 110.434
55.5889 97.6663
55.6981 85.5773
55.8125 74.2805
55.9327 63.8889
56.0596 54.5158
56.1937 46.2742
56.3359 39.2773
56.4869 33.6383
56.6475 29.4703
56.8182 26.8865
57 26
57.2272 27.0354
57.4407 30.0536
57.6413 34.9225
57.8301 41.5099
58.0078 49.6836
58.1755 59.3115
58.3341 70.2612
58.4844 82.4008
58.6273 95.5979
58.7639 109.72
58.895 124.636
59.0215 140.213
59.1443 156.318
59.2644 172.821
59.3827 189.587
59.5 206.486
59.6173 223.385
59.7356 240.152
59.8557 256.655
59.9785 272.761
60.105 288.339
60.2361 303.256
60.3727 317.38
60.5156 330.579
60.6659 342.72
60.8245 353.672
60.9922 363.302
61.1699 371.478
61.3587 378.068
61.5593 382.94
61.7728 385.961
62 387
62.5453 386.379
63.0576 384.544
63.5392 381.565
63.9922 377.508
64.4188 372.444
64.8213 366.439
65.2018 359.563
65.5625 351.882
65.9056 343.467
66.2334 334.384
66.548 324.703
66.8516 314.492
67.1464 303.818
67.4346 292.75
67.7184 281.356
68 269.705
68.2816 257.866
68.5654 245.905
68.8536 233.891
69.1484 221.894
69.452 209.98
69.7666 198.219
70.0944 186.678
70.4375 175.426
70.7982 164.531
71.1787 154.061
71.5812 144.085
72.0078 134.671
72.4608 125.888
72.9424 117.802
73.4547 110.484
74 104
74.7029 96.6122
75.4044 89.5532
76.1032 82.8167
76.7979 76.3966
77.487 70.2866
78.1693 64.4807
78.8434 58.9726
79.5078 53.7562
80.1613 48.8252
80.8024 44.1736
81.4297 39.7951
82.042 35.6835
82.6378 31.8327
83.2157 28.2366
83.7744 24.8888
84.3125 21.7833
84.8286 18.9138
85.3214 16.2743
85.7895 13.8584
86.2314 11.6601
86.646 9.67317
87.0316 7.89141
87.3871 6.30865
87.7109 4.91873
88.0018 3.71546
88.2584 2.69266
88.4793 1.84417
88.6631 1.1638
88.8084 0.64537
88.9139 0.282713
88.9783 0.0696488
89 0
89.2726 0.297909
89.5288 1.14382
89.7696 2.50116
89.9961 4.33339
90.2094 6.60393
90.4106 9.27623
90.6009 12.3137
90.7812 15.6799
90.9528 19.3381
91.1167 23.2518
91.274 27.3845
91.4258 31.6995
91.5732 36.1604
91.7173 40.7306
91.8592 45.3735
92 50.0525
92.1408 54.7311
92.2827 59.3728
92.4268 63.9409
92.5742 68.3989
92.726 72.7103
92.8833 76.8385
93.0472 80.7468
93.2188 84.3989
93.3991 87.7581
93.5894 90.7878
93.7906 93.4514
94.0039 95.7125
94.2304 97.5345
94.4712 98.8808
94.7274 99.7148
95 100
95.2345 99.712
95.4685 98.8749
95.7016 97.5252
95.9332 95.6995
96.1631 93.4346
96.3906 90.7669
96.6153 87.733
96.8368 84.3697
97.0547 80.7136
97.2684 76.8011
97.4775 72.669
97.6816 68.3539
97.8802 63.8923
98.0728 59.321
98.259 54.6764
98.4383 49.9953
98.6103 45.3142
98.7745 40.6698
98.9305 36.0986
99.0777 31.6373
99.2158 27.3225
99.3443 23.1908
99.4627 19.2789
99.5706 15.6232
99.6675 12.2606
99.753 9.22745
99.8266 6.56051
99.8878 4.29636
99.9362 2.47163
99.9713 1.12291
99.9928 0.28683
100 0