2011-11-06 5 views
14

私はUIBezierPathを使用していますが、この問題は図面のパスではなくコントロールのコントロールポイントに関係しています。与えられた点の集合を与えて、私はパスをレンダリングすることができます。しかし、私は写真曲線エディタ(How to implement a Photoshop Curves editor in UIKit)のような滑らかな線を持つコントロールポイントを計算する方法を理解することができませんでした。ポイントのセットを指定してスムーズなパスのコントロールポイントを計算する方法は?

私が見た最も近い答えはここにある:how can i trace the finger movement on touch for drawing smooth curves?

しかし、私はまだ適切な計算を把握することはできません。コードでそれを要約すると:

for (int i = 0; i< points; i++) 
{ 
    ... 

    [path addQuadCurveToPoint:nextPoint controlPoint:WTF]; 
} 
+5

沈黙はとても痛いので痛いです。 – akaru

+0

あなたは与えられたポイントのそれぞれを正確に通り抜けたいですか?または、より滑らかな曲線が所定の点のいくつかの近くを通過することを希望しますか? –

+0

@robmayoffもっと簡単な操作であれば、closeは十分だと思います。 – akaru

答えて

12

あなたがにリンクされた画像は、二次曲線を使用していない例であるので、私は画像ではなくコードで を実行するつもりです。

ios(およびos x)の下のベジエパスは、基本的に描画コマンドとポイントのリストです。例えば:で

[path moveTo:CGMakePoint(1,1)]; 
[path curveToPoint:(10,10) controPoint1:(3,7) controlPoint2:(4,1)]; 
[path curveToPoint:(10,10) controPoint1:(15,17) controlPoint2:(21,11)]; 
[path closePath]; 

結果:ベジエ・パスに

moveto (1,1)  
curveto (10,10) (3,7) (4,1) 
curveto (20,0) (15,17) (21,11)  
closepath 

制御点が点からカーブの方向と速度を制御します。最初のコントロールポイント(cp)は、前のポイントを終了するカーブの方向と速度を制御し、2番目のコントロールポイントは、カーブしているポイントのカーブの方向とカーブを制御します。二次曲線(addQuadCurveToPoint:controlPoint:を使用した場合)については、hereのドキュメントにあるように、これらの点は同じです。

点の集合に沿って滑らかな曲線を得るには、cp1とcp2を互いに同一直線にし、その線をその線分の両端の点に平行にする必要があります。

Annotated curve

このようなものになります。今

[path moveTo:2]; 
[path curveTo:3 controlPoint1:cp1 controlPoint2:cp2]; 

CP1とCP2は、いくつかの定数線路の長さを選択すると、いくつかの形状をしていることにより計算することができます(私はすべての私のラインの方程式を忘れるのが、彼らは」セグメント番号を指定するには# - >#を使用し、セグメントのcurveto呼び出しにはコントロールポイントを指定するには# - >#(cp#)を使用します。

次の問題は、2→3セグメントから3> 4セグメントに滑らかにカーブさせることです。コードのこの時点で、2〜3(cp2)で計算されたコントロールポイントが必要です。これから線の長さを一定にすると(曲線の鋭さが制御されます)、2> 3(cp2)で点線の線を引いて、3から4までのcp1を計算できます。次に、3> 4(cp1)と同一直線上にあり、点3と点4の形をした線に平行な3> 4(cp2)を計算します。リンスし、あなたのポイント配列を繰り返します。

+1

お返事ありがとうございます。残念ながら、リンクを読んだ後、私はまだ正しい方法を決定することができません。私は私の脳を責める。 – akaru

+0

コントロールポイントを計算するコードを書く方法はありません。 –

4

これはどれくらい助けになるのか分かりませんが、私はこのアプリでノートに沿ってカーブしたパスを実装するのに似たようなことをしなければなりませんでした(www.app.net/hereboy)。本質的には、3つの曲線を持つパスです。

これを行うには、25%と75%のマークで4つの曲線、開始点、終了点、2つの制御点を作成しました。

//create points along the keypath for curve. 
CGMutablePathRef curvedPath = CGPathCreateMutable(); 
const int TOTAL_POINTS = 3; 
int horizontalWiggle = 15; 

int stepChangeX = (endPoint.x - viewOrigin.x)/TOTAL_POINTS; 
int stepChangeY = (endPoint.y - viewOrigin.y)/TOTAL_POINTS; 

for(int i = 0; i < TOTAL_POINTS; i++) { 
    int startX = (int)(viewOrigin.x + i * stepChangeX); 
    int startY = (int)(viewOrigin.y + i * stepChangeY); 

    int endX = (int)(viewOrigin.x + (i+1) * stepChangeX); 
    int endY = (int)(viewOrigin.y + (i+1) * stepChangeY); 

    int cpX1 = (int)(viewOrigin.x + (i+0.25) * stepChangeX); 
    if((i+1)%2) { 
     cpX1 -= horizontalWiggle; 
    } else { 
     cpX1 += horizontalWiggle; 
    } 
    int cpY1 = (int)(viewOrigin.y + (i+0.25) * stepChangeY); 

    int cpX2 = (int)(viewOrigin.x + (i+0.75) * stepChangeX); 
    if((i+1)%2) { 
     cpX2 -= horizontalWiggle; 
    } else { 
     cpX2 += horizontalWiggle; 
    } 
    int cpY2 = (int)(viewOrigin.y + (i+0.75) * stepChangeY); 

    CGPathMoveToPoint(curvedPath, NULL, startX, startY); 
    CGPathAddCurveToPoint(curvedPath, NULL, cpX1, cpY1, cpX2, cpY2, endX, endY); 
} 

幸運:

は、ここで私はこれを行うために書いたコードです!

関連する問題