2013-04-07 10 views
8

私はいくつかのポイントを通してラインカーブを作る方法を探しています。カーブに文脈を与えるためには、ポイントに入る線の角度に文脈を与えることが必要であるかもしれないと私は考えていましたが、3点を使用することが望ましいでしょう。ポイントを使ってラインカーブを作成する方法

一般に、開始点P1、制御点P2、および終了点P3の場合、線はP1からP2にカーブし、次にP2からP3にカーブする必要があります。ここでは実際には

は私が達成したい効果の完璧な例です:

Irwin Hall Spline

私はこれを行うことができれば、私は本当に永遠に感謝されます! Javaでは

これまでのところ、私は(はPath2D.Doubleでcurvetoといったを使用して)Cub icCurve2D.Double、などQuadCurve2D.Doubleようなもので遊んでみましたともPath2D.Doubleましたが、無駄に - 描かれている曲線が通過するのにも近くありませんコントロールポイントが指定されています。ここで

は、私がこれまで試してみました方法の画像です:

enter image description here

そして、ここでは、私は、画像内の点と曲線を生成するために使用されるコードは次のとおりです。

Graphics2D g = (Graphics2D) window.getGraphics(); 
    g.setColor(Color.blue); 
    int d = 4; 

    // P0 
    int x0 = window.getWidth()/8; 
    int y0 = 250; 
    g.drawString("P0", x0, y0 + 4*d); 
    g.fillRect(x0, y0, d, d); 

    // P1 
    int x1 = (window.getWidth()/7)*2; 
    int y1 = 235; 
    g.drawString("P1", x1, y1 + 4*d); 
    g.fillRect(x1, y1, d, d); 

    // P2 
    int x2 = (window.getWidth()/2); 
    int y2 = 200; 
    g.drawString("P2", x2, y2 - 2*d); 
    g.fillRect(x2, y2, d, d); 

    // P3 
    int x3 = (window.getWidth()/7)*5; 
    int y3 = 235; 
    g.drawString("P3", x3, y3 + 4*d); 
    g.fillRect(x3, y3, d, d); 

      // P4 
    int x4 = (window.getWidth()/8)*7; 
    int y4 = 250; 
    g.drawString("P4", x4, y4 + 4*d); 
    g.fillRect(x4, y4, d, d); 

    g.setColor(Color.cyan); 
    QuadCurve2D quadCurve = new QuadCurve2D.Double(x0, y0, x2, y2, x4, y4); 
    g.draw(quadCurve); 


    g.setColor(Color.YELLOW); 
    CubicCurve2D.Double cubicCurve = new CubicCurve2D.Double((double)x0, (double)y0, 
                  (double)x1, (double)y1, 
                  (double)x2, (double)y2, 
                  (double)x4, (double)y4); 
    g.draw(cubicCurve); 


    g.setColor(Color.red);  
    Path2D.Double path1 = new Path2D.Double(); 
    path1.moveTo(x1, y1); 
    path1.curveTo(x0, y0, x2, y2, x4, y4); 
    g.draw(path1); 

私が書いた折れ線グラフ上の頂点間の遷移を「滑らかにしたい」ということが、曲線を曲線を通るようにしたいという私の理由です。誰もがそれを言及する前にJFree Chartはオプションではありません。私は使用されているさまざまな種類の曲線とスプラインがあることを理解していますが、私は彼らの動作の仕方や私のニーズに合ったものを実装する方法を正確に理解することができませんでした。

事前に感謝の意を表します。

+0

点の配列を通って曲線を描くように求めていますか? –

+0

はい、Irwin-Hallスプライン上の各点が配列内の要素であると考えてください。 –

答えて

9

コントロールポイントのアイデアが不足していると思います。コントロールポイントは、通常、パス自体にはありません。代わりに、パスの曲線がポイント間でどのように整形されるかを制御します。詳細については、spline tutorialを参照してください。

問題が発生した時点で、曲線上にポイントがありますが、実際のコントロールポイントはありません。 Cardinal Splineのようないくつかのテクニックがあります。これは制御点を導出して、あなたが言及している曲線描画APIの1つに渡すためのものです。 Path2D.Doubleオプションが必要なので、個々の曲線をスムーズにつなぎ合わせることができます。

ので、代わりに

Path2D.Double path1 = new Path2D.Double(); 
path1.moveTo(x1, y1); 
path1.curveTo(x0, y0, x2, y2, x4, y4); 
g.draw(path1); 

の、P3にP1からP2に描画するためにあなたがcxcy座標は、キュービックスプラインごとに2つの制御点派生コントロールポイントである

Path2D.Double path1 = new Path2D.Double(); 
path1.moveTo(x1, y1); 
path1.curveTo(cx1a, cy1a, cx1b, cy1b, x2, y2); 
path1.curveTo(cx2a, cy2a, cx2b, cy2b, x3, y3); 
g.draw(path1); 

をしたいですセグメント。おそらく、ここで

cx1a = x1 + (x2 - x1)/3; 
cy1a = y1 + (y2 - y1)/3; 
cx1b = x2 - (x3 - x1)/3; 
cy1b = y2 - (y3 - y1)/3; 
cx2a = x2 + (x3 - x1)/3; 
cy2a = y2 + (y3 - y1)/3; 
cx2b = x3 - (x3 - x2)/3; 
cy2b = y3 - (y3 - y2)/3; 

パターンは、内部ポイント(この場合のみP2)のために前後の制御点(C1B及びC2A)は前の点の間の線の傾きによって相殺されることであるとそれの後(P1とP3)。エッジ点については、制御点は、その点と次に近い点との間の勾配に基づいている。

ドメイン固有の情報がある場合は、異なるコントロールポイントを選択することができます。たとえば、終点のスロープを0にしたい場合があります。

+0

cx1bとcy1bは重複していませんか?彼らはcx1a cy1a cx1b cy1bではないはずですか? –

+0

ありがとう@JamesC。今修正されました。 – xan

+0

あまりにも問題がなければ、コントロールポイントを構築するためにそのようなxとyの値を選んだ理由について、あなたは少し光を当てることができますか?なぜコントロールポイントの最後のペアを除くすべてがx1、y1を使用するのですか?また、2番目のペアcx1bとcy1bでは、カーブが近づいているポイントの後ろのポイントの位置に依存するように見えますが、最後のペアでは、最後のポイントに近づいているので、余分なステップをとることはできません。だから、将来のポイントx3、y3を使って、2番目のポイントに近づいていくカーブの角度を正当化することを前提としています。 –

2

も多分これが助けることができる:例によるP

キャットマル-Romの曲線と同じ原則異なるLANG ... http://schepers.cc/svg/path/dotty.svg

+0

Catmull-romスプラインは、曲線を描画する方法でIrwinホールスプラインとは異なります。 http://blog.ivank.net/interpolation-with-cubic-splines.html –

+0

[この例](http://postimg.org/)を検討した場合、リンクJobanをありがとう、このリソースを確認し、いくつかの点を描画します。 image/izjajqfw7 /)は、あなたが提供したリンクで作成した曲線(少なくとも私の場合)は、最後の点と最後の点の間にはるかに大きな値が存在するという印象を誤って与えることがあります。泳いでいるCatmull-Romの例は受け入れられますが、実装は明確ではありません。 –

+0

だから、catmull-romスプラインが必要なのではないでしょうか。おそらくもっと簡単になるはずです。 –

2

基本的に何を求めていることですが、キュービックスプライン補間で、私がいましたこのプログラムをオンラインで見つけることができるInterp2.java。実際には、多項式スプラインと3次スプラインが含まれます。

残念ながら実際のクラスではなく、実際のクラスではありませんが、コードを見ても、どうやってそれを行ったかがわかります。それはいつも良いことです。

関連する問題