私はベジェ曲線 (Core Graphics の任意の曲線) を取り、別の 2 つの終点を指定して比例的に縮小 (または拡大) しようとしています。私にはそのようなアプローチがありますが、最終的には曲線を「平坦化」し、形状を正確に保持することはできません。コードまたはロジックを台無しにしてしまったのかもしれませんが、制御点と一緒に 2 つの元の点があります。別の終点のセットが与えられた場合、適切な制御点を計算して、新しい終点間で同じ形状を生成したいと考えています。
1 つのコントロール ポイントを計算するメイン コードは次のとおりです。
CGPoint (^ScaledCtrlPoint)(CGPoint, CGPoint, CGPoint, CGPoint, CGPoint) = ^CGPoint (CGPoint refPoint1, CGPoint refPoint2, CGPoint bevPoint1, CGPoint bevPoint2, CGPoint ctrlPoint){
//Normalize points to refPoint1
refPoint2.x -= refPoint1.x; refPoint2.y -= refPoint1.y;
ctrlPoint.x -= refPoint1.x; ctrlPoint.y -= refPoint1.y;
//Normalize bevPoints to bevPoint1
bevPoint2.x -= bevPoint1.x; bevPoint2.y -= bevPoint1.y;
//Calculate control point angle
CGFloat theta = PointTheta(refPoint2);
CGFloat refHyp = (refPoint2.y != 0.0f) ? refPoint2.y / sinf(theta) : refPoint2.x / cosf(theta);
theta = PointTheta(bevPoint2);
CGFloat bevHyp = (bevPoint2.y != 0.0f) ? bevPoint2.y / sinf(theta) : bevPoint2.x / cosf(theta);
theta = PointTheta(ctrlPoint);
CGFloat ctrlHyp = (ctrlPoint.y != 0.0f) ? ctrlPoint.y / sinf(theta) : ctrlPoint.x / cosf(theta);
ctrlHyp *= (bevHyp / refHyp);
return CGPointMake(bevPoint1.x + cosf(theta) * ctrlHyp, bevPoint1.y + sinf(theta) * ctrlHyp);
};
新しいコントロール ポイントを計算するために使用しているbevPoints
新しいポイントです。refPoints
とctrlPoint
は、ベジエ曲線の元のポイントです。ご覧のとおり、元のエンドポイントと新しいエンドポイントの比率と同じ比率で ctrlPoint を縮小しようとしています (拡大することもできます)。
また、入射角の計算に使用する別の関数も使用します。それはとても簡単です:
CGFloat PointTheta(CGPoint point){
//This assumes an origin of {0, 0} and returns a theta for the given point
CGFloat theta = atanf(point.y / point.x);
//Using arc tan requires some adjustment depending on the point quadrant
if (point.x == 0.0f) theta = (point.y >= 0.0f) ? M_PI_2 : M_PI + M_PI_2;
else if (point.x < 0.0f) theta += M_PI;
else if (point.x > 0.0f && point.y < 0.0f) theta += (M_PI * 2);
return theta;
}