1

私はベジェ曲線 (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新しいポイントです。refPointsctrlPointは、ベジエ曲線の元のポイントです。ご覧のとおり、元のエンドポイントと新しいエンドポイントの比率と同じ比率で 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;
}
4

1 に答える 1

2

CGAffineTransform私はパラメータを使って計算します

(a, b, -b, a, tx, ty)

(つまり、スキューのない変換)古いエンドポイントを新しいエンドポイントにマップし、この変換を古いコントロールポイントに適用して、新しいコントロールポイントを取得します。

2つの古いエンドポイントが2つの新しいエンドポイントにマップされるという条件は、a、b、tx、tyの4つの方程式を与え、これらの方程式は三角関数なしでも解くことができます。

于 2012-09-04T14:19:02.973 に答える