2017-01-29 18 views
0

私の現在のjavafxプロジェクトのうち、私はVenn Diagramsを使っています。私はShape.intersectを利用して、私が個人的に作業しなければならない数学計算の量を簡単にしたい(そしてPathオブジェクトでの作業を避けたい)。 Shape.intersectは完全な形を作りますが、それはちょっと翻訳/移動されていますし、どれくらい戻したらいいのか分かりません。理想的には、2つの元の図形が交差する場所、つまり新しい交差点が元の図形にシームレスに収まるように、交差領域を正確に作成したいと考えています。Shape.intersectの結果のシェイプが、正しくない位置に表示されるのはなぜですか?

現時点では、私のコードはウィンドウと一緒に拡大する3つのVenn Diagramを生成します。私はサークルの3つの中心点と他の重要な交差点のおおよその近似点にアクセスできます。これらの他の点は、3つの円がすべて同じサイズで対称であることを確かめるためにsinとcosの値に依存しているため、近似されています。 enter image description here

あなたが見ることができるように、円のAとBの交点を:

は、私は(ポイントは/文字がペイントに外部から追加されたが、根底にある画像は、私のアプリは今生成するものである)、次の画像を嘲笑しました(青で示されている)がマークから外れています。

これを生成するには、基になるキャンバスをウィンドウサイズに合わせてスケーリングし、円の中心を配置する場所を計算し、同じ半径の3つすべてを描画します。すべての余分な綿毛を切り出し、私のコードは、基本的に次のようになります。

// Constructor creates 3 circles and adds to canvas 
Circle a = new Circle(); 
canvas.getChildren().add(a); 
// etc. for the other two circles 

// And also makes a Shape object to hold the intersection 
Shape ab = Shape.intersect(a,b); // initially empty 
canvas.getChildren().add(ab); 
後で

...

// Resizing the window calls an update function 
// which recalculates the circles' centers and 
// radii and then updates them. Since circles are 
// drawn from upper left corner, the relocate call 
// makes sure to subtract the radius to center it 
a.setRadius(radius); 
a.relocate(acx-radius,acy-radius); 

そして(更新機能でも)交差点ロジック:

canvas.getChildren().remove(ab); 
ab = Shape.intersect(a,b); 

// Can relocate to point c, but this doesn't do the job either (see below) 
ab.relocate(pcx,pcy); 

// Add the new intersection back to the canvas 
canvas.getChildren().add(ab); 

私は結果の交差点形状をC点に再配置しようとしましたが、まだ正しく整列されていないため、その点の近似値があまりにも丸くなっているかどうかはわかりません:

enter image description here

私は、これはサイズ変更に変更し、適切に更新されませんますレイアウト境界/視覚境界か何かとは何かを持っているかもしれませんオフセット推測しているが、私は、ドキュメントを見て、長期的に過ごし、それを理解できませんでした。

理想的には、円C自体が近似/丸めによって生成されるので、点Cを手で計算する必要はありません。これにより、Cを実質的に正確にすることは事実上不可能になります。誰かが元のサークルだけを使用できる解決策を教えてくれることを願っていますが、現在のキャンバスのサイズに関係なく、正しい場所に交差点を表示するようなものはすべて取ります。

要約:Shape.intersectによって返されるシェイプは、シェイプが作成される2つのシェイプの中央に表示されるようにするにはどうすればよいですか?御時間ありがとうございます。

+1

問題を再現しましたが、[正常に動作しました](http://imgur.com/a/42vf9)。メニューバーとステータスバーがあります。交差点がこれらの2つの要素のいずれも含まない座標セットにバインドされている可能性がありますか?たぶんあなたの図形をバインドまたはサイズ変更するコードを共有した場合、修正する方が簡単でしょうか? – MikaelF

+0

お返事ありがとうございます。私はコードが非常に長くて面倒なので、私が問題の非常に簡潔な例を作ることができるかどうかを見極めるつもりです。今はそれをそのままアップロードするのは逆効果です。私は今日仕事を終えてから数時間後に更新します。問題は私が使用しているキャンバスオブジェクトのサイズ変更にあると思われますので、共有することが間違いなく重要です。 – Prester

答えて

0

私は問題を把握することができました。私はthis postに触発された自動サイズ変更のキャンバスオブジェクトを使って作業していました。ここでStackOverflowで見つけました。これまでに変更するリンクの場合、私はそこから借りたコードのキービットは、次のように見えた:

「キャンバス」は、Canvasオブジェクトのプライベートインスタンスであり、この全体の関数を呼び出すクラスの中にあった
// Update function when the window is resized 
@Override 
protected void layoutChildren() { 
    final double top = snappedTopInset(); 
    final double right = snappedRightInset(); 
    final double bottom = snappedBottomInset(); 
    final double left = snappedLeftInset(); 

    width = getWidth() - left - right; 
    height = getHeight() - top - bottom; 

    // Update the layout 
    canvas.setLayoutX(left); 
    canvas.setLayoutY(top); 

    if (width != canvas.getWidth() || height != canvas.getHeight()) { 
     // Resize 
     canvas.setWidth(width); 
     canvas.setHeight(height); 

     // Determine center 
     cx = width/2; 
     cy = height/2; 

     // Determine radius of circles 
     radius = 0.25 * Math.min(width, height); 

     // Clear and redraw circles 
     clear(); 
     redraw(); 
    } 
} 

CanvasPane拡張ペイン。

私が見つけたこと 上記のコードは、CanvasPaneのchildren()にCirclesのようなオブジェクトを追加したときに問題が発生します。私のredraw()メソッドはサークルの中心を移動して半径を調整しただけです。 実際の円の実際のキャンバスオブジェクトのように.setLayoutX()と.setLayoutY()関数を更新したことはありません。したがってCanvasPaneのサイズを変更すると、レイアウト情報が一貫して更新されず、すべての円の基本レイアウト位置が同期しなくなります。

だから、ここの修正は、次の更新レイアウト・セクションを変更することです:

// Update the layout 
for (Node n : getChildren()) { 
    n.setLayoutX(left); 
    n.setLayoutY(top); 
} 

これは、円の配置位置を更新し、他のオブジェクトは、私としてCanvasPane(だけでなく、キャンバスに追加結果として得られた交差部分を実際に正しい位置にした。

私は元来の質問にもっと多くのコードを含めるべきだったのは間違いありません。うまくいけば、いつか誰かが私と同じ問題を抱え、この答えを見つけることができるでしょう。

関連する問題