@@ -364,23 +364,38 @@ void ce::Curve_ID::reverse_points()
364
364
// ---------------------------------------------------------------------
365
365
double ce::Curve_ID::get_value (double ratio, double st, double ed)
366
366
{
367
- if (!ISINRANGE (ratio, 0 , 1 )) return 0 ;
367
+ // 進捗が0~1の範囲外であった場合
368
+ if (!ISINRANGE (ratio, 0 , 1 ))
369
+ return 0 ;
370
+ // 進捗に相当する区間を調べる
368
371
for (int i = 0 ; i < control_points.size () - 1 ; i++) {
369
372
if (ISINRANGE (ratio, control_points[i].pt_center .x / (double )CE_GR_RES, control_points[i + 1 ].pt_center .x / (double )CE_GR_RES)) {
370
373
double range = (control_points[i + 1 ].pt_center .x - control_points[i].pt_center .x ) / (double )CE_GR_RES;
371
- double x1 = (control_points[i].pt_right .x - control_points[i].pt_center .x ) / (control_points[i + 1 ].pt_center .x - control_points[i].pt_center .x );
372
- double y1 = (control_points[i].pt_right .y - control_points[i].pt_center .y ) / (control_points[i + 1 ].pt_center .y - control_points[i].pt_center .y );
373
- double x2 = (control_points[i + 1 ].pt_center .x - control_points[i + 1 ].pt_left .x ) / (control_points[i + 1 ].pt_center .x - control_points[i].pt_center .x );
374
- double y2 = (control_points[i + 1 ].pt_center .y - control_points[i + 1 ].pt_left .y ) / (control_points[i + 1 ].pt_center .y - control_points[i].pt_center .y );
375
- double st2 = st + control_points[i].pt_center .y * (ed - st) / (double )CE_GR_RES;
376
- double ed2 = st + control_points[i + 1 ].pt_center .y * (ed - st) / (double )CE_GR_RES;
374
+ // 区間内での進捗の相対値(0~1)
375
+ double ratio2 = (ratio - control_points[i].pt_center .x / (double )CE_GR_RES) / range;
376
+ // 区間ごとの制御点1のX座標(相対値、0~1)
377
+ double x1 = (control_points[i].pt_right .x - control_points[i].pt_center .x ) / (double )(control_points[i + 1 ].pt_center .x - control_points[i].pt_center .x );
378
+ // 区間ごとの制御点1のY座標(相対値)
379
+ double y1 = (control_points[i].pt_right .y - control_points[i].pt_center .y ) / (double )(control_points[i + 1 ].pt_center .y - control_points[i].pt_center .y );
380
+ // 区間ごとの制御点2のX座標(相対値、0~1)
381
+ double x2 = (control_points[i + 1 ].pt_left .x - control_points[i].pt_center .x ) / (double )(control_points[i + 1 ].pt_center .x - control_points[i].pt_center .x );
382
+ // 区間ごとの制御点2のY座標(相対値)
383
+ double y2 = (control_points[i + 1 ].pt_left .y - control_points[i].pt_center .y ) / (double )(control_points[i + 1 ].pt_center .y - control_points[i].pt_center .y );
384
+
385
+ // 区間ごとの始値、終値(相対値ではなく、実際の値)
386
+ double st2 = st + control_points[i].pt_center .y / (double )CE_GR_RES * (ed - st);
387
+ double ed2 = st + control_points[i + 1 ].pt_center .y / (double )CE_GR_RES * (ed - st);
388
+ // y1,y2を相対値から実際の値に修正
389
+ y1 = st2 + (ed2 - st2) * y1;
390
+ y2 = st2 + (ed2 - st2) * y2;
391
+ // ベジェの計算
377
392
double tl = 0 ;
378
393
double tr = 1 ;
379
394
double ta = 0.5 * (tl + tr);
380
395
double xta;
381
- for (int j = 1 ; j < 10 ; j++) {
396
+ for (int j = 0 ; j < 10 ; j++) {
382
397
xta = (1 - 3 * x2 + 3 * x1) * std::pow (ta, 3 ) + (x2 - 2 * x1) * 3 * std::pow (ta, 2 ) + 3 * x1 * ta;
383
- if (ratio < xta) tr = ta;
398
+ if (ratio2 < xta) tr = ta;
384
399
else tl = ta;
385
400
ta = 0.5 * (tl + tr);
386
401
}
0 commit comments