2016-09-12 5 views
2

これは初めての投稿です。私は現在、JavaFXでオリンピック・リングを作成し、正しい場所で交差させる必要がある割り当てを行っています。JavaFXオリンピック・リングが正しい順序で重複しています

これは、見えるようになっているものである:

olympic rings http://ksuweb.kennesaw.edu/~ashaw8/cs1302-07-Fall16/assignments/images/OlympicRings.png

現在、リングが交差するが、彼らは、私は、オブジェクトを作成したために支配しています。青は交差すると黄色に覆われ、黄色は交差するときに黒で覆われます。オリンピックリングの写真で見るように、黄色と青が交差し、黄色は青色に覆いますが、青色は黄色に覆います時間。それぞれのリングは、一度交差するともう一方のリングで覆われますが、もう一方のリングはそれを覆います。

誰かが適切に交差するように正しい方向に向けることができれば、それは素晴らしいことでしょう。ここで

は、私がこれまで持っているコードです:

package com.company; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Circle; 
import javafx.stage.Stage; 

public class OlympicRings extends Application{ 

    public void start(Stage primaryStage) { 

     //creates a new object, which will be the first circle 
     Circle circle1 = new Circle(); 
     circle1.setCenterX(100); //sets the x coordinate for the center of the circle 
     circle1.setCenterY(100); //sets the y coordinate for the center of the circle 
     circle1.setRadius(50); //sets the radius of the circle to 50, makes the diameter 100 
     circle1.setStroke(Color.BLUE); //sets the color of the circle 
     circle1.setStrokeWidth(10); //sets the thickness of the lines 
     circle1.setFill(null); //sets the color of the inside of the circle, set to null to enable overlap 

     Circle circle2 = new Circle(); //creates additional circles 
     circle2.setCenterX(160); 
     circle2.setCenterY(150); 
     circle2.setRadius(50); 
     circle2.setStroke(Color.YELLOW); 
     circle2.setStrokeWidth(10); 
     circle2.setFill(null); 

     Circle circle3 = new Circle(); 
     circle3.setCenterX(220); 
     circle3.setCenterY(100); 
     circle3.setRadius(50); 
     circle3.setStroke(Color.BLACK); 
     circle3.setStrokeWidth(10); 
     circle3.setFill(null); 

     Circle circle4 = new Circle(); 
     circle4.setCenterX(280); 
     circle4.setCenterY(150); 
     circle4.setRadius(50); 
     circle4.setStroke(Color.GREEN); 
     circle4.setStrokeWidth(10); 
     circle4.setFill(null); 

     Circle circle5 = new Circle(); 
     circle5.setCenterX(340); 
     circle5.setCenterY(100); 
     circle5.setRadius(50); 
     circle5.setStroke(Color.RED); 
     circle5.setStrokeWidth(10); 
     circle5.setFill(null); 

     //creating the pane that will display the circle 
     Pane pane = new Pane(); 
     pane.getChildren().add(circle1); //each of these adds the various circles to the display of the pane 
     pane.getChildren().add(circle2); 
     pane.getChildren().add(circle3); 
     pane.getChildren().add(circle4); 
     pane.getChildren().add(circle5); 

     Scene scene1 = new Scene(pane, 440, 250); //creates the parameters of the pane 
     primaryStage.setTitle("Olympic Rings"); //names the pane 
     primaryStage.setScene(scene1); //picks what will go in the pane 
     primaryStage.show(); //shows the scene i've created 
    } 
} 
+1

サークルを単独で使用することはできません。おそらく、サークル全体ではなく、[Arcs](https://docs.oracle.com/javafx/2/api/javafx/scene/shape/Arc.html)を使用すると、これを実現できますか? – Petesh

答えて

2

これはCircle秒で達成することは困難です。これにより、clipプロパティが頻繁に使用され、その結果のコードは容易に読み込めません。

代わりにArcsを使用して、リングの一部を描画することができます。カバー部分を追加する前に、リングのカバー部分を親に追加するだけです。

例は、最初の2つのリングのために:質問の

private static Arc createArc(double radius, 
          double centerX, double centerY, 
          double fromAngle, double toAngle, 
          Paint stroke, 
          double strokeWidth) { 
    Arc arc = new Arc(centerX, centerY, radius, radius, fromAngle, toAngle - fromAngle); 
    arc.setFill(null); 
    arc.setStroke(stroke); 
    arc.setStrokeWidth(strokeWidth); 

    return arc; 
} 

@Override 
public void start(Stage primaryStage) { 
    Pane pane = new Pane(
      createArc(50, 60, 60, 90, 315, Color.BLUE, 10), // part of the blue ring containing part covered by yellow 
      createArc(50, 110, 110, 0, 360, Color.YELLOW, 10), 
      createArc(50, 60, 60, -45, 90, Color.BLUE, 10) // part covering the yellow ring 
    ); 

    Scene scene = new Scene(pane); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

ありがとう!私は実際に働いた残りの弧を見つけ出すことができました。一番上のコンストラクタがどのように動作しているかを私が理解する助けになりますか?私は、Arcを返すコンストラクタを作成し、それを利用するためにStartクラスのコンストラクタを呼び出しています。私は、コンストラクタのすぐ下にある行が何をするのか、混乱しています。これは、Arc arc = new Arcで始まる行です。なぜ半径を2回リストしているのですか?なぜtoAngle - fromAngleという行がありますが、ペイントストロークはありませんか?申し訳ありませんが、読みにくい場合は、私はこの周りに頭をラップしようとしています。 – TomBombadil

+0

@TomBombadilここでjavadocの説明を参照できます。https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/Arc.html#Arc-double-double-double-double -double-double- 'Arc'では楕円形を描画でき、円の特殊な場合は' radiusX == radiusY'となります。 BTW 'createArc'はコンストラクタではなく、メソッドです。コンストラクターは戻り値の型を持たず、包含するクラスのインスタンスの作成にのみ使用できます。 – fabian

1

おかげで、私は次の解決策を考え出すたくさんの楽しみを持っていた、アルゴリズムのJavadocを参照してください。

package olympicrings; 

import java.util.Arrays; 
import java.util.Collections; 
import java.util.List; 

import javafx.scene.layout.Pane; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Arc; 

/** 
* This helper class knows how to paint the next olympic ring into a {@code Pane}. 
* It is not limited to 5 olympic rings, it can draw as many (or few) as desired. 
* The algorithm it follows is: 
* <ol> 
* <li>Each ring consists of 2 arcs (half-circles) of the same color, of course. 
*  Imagine the line connecting the center of the previous ring to the center 
*  of the current: we place one arc on the LEFT of this line and one arc on 
*  the RIGHT. Let's call them arcs L and R. These need to be added to the 
*  children {@code Node}s of the {@code Pane} at the correct order.</li> 
* <li>The placement of arc L depends on whether the current ring is at the top 
*  row or at the bottom: 
*  <ul> 
*   <li>TOP: It goes below arc L of the previous ring</li> 
*   <li>BOTTOM: It goes below arc R of the previous ring</li> 
*  </ul> 
* </li> 
* <li>Arc R is always placed last in the list of the children of the {@code Pane}.</li> 
* <li>Advance the position of the next ring, taking into account the desired 
*  ring radius and stroke width.</li> 
* </ol> 
* <p> 
* Usage: 
* <pre><code> 
* OlympicRingsPaintingContext ctx = new OlympicRingsPaintingContext(thePane, 50, 10); 
* ctx.paintNextRing(Color.BLUE); 
* ... 
* </code></pre> 
*/ 
public class OlympicRingsPaintingContext { 

    /** 
    * A handy constant containing the standard olympic colors. Could be used as follows 
    * to paint the standard olympic rings: 
    * <pre><code> 
    * OlympicRingsPaintingContext ctx = new OlympicRingsPaintingContext(thePane, 50, 10); 
    * OlympicRingsPaintingContext.STANDARD_OLYMPIC_COLORS.forEach(ctx::paintNextRing); 
    * </code></pre> 
    */ 
    public static final List<Color> STANDARD_OLYMPIC_COLORS = Collections.unmodifiableList(Arrays.asList(Color.BLUE, Color.YELLOW, Color.BLACK, Color.GREEN, Color.RED)); 

    private static final double[] TOP_START_ANGLES = new double[] {45, 225}; 
    private static final double[] BOTTOM_START_ANGLES = new double[] {315, 135}; 

    private Pane pane; 
    private double radius; 
    private double strokeWidth; 
    private double curx; 
    private double cury; 
    private double topy; 
    private double bottomy; 
    private double startAngleL; 
    private double startAngleR; 
    private int prevIndexL; 
    private int prevIndexR; 

    public OlympicRingsPaintingContext(Pane pane, double radius, double strokeWidth) { 
     this.pane = pane; 
     this.radius = radius; 
     this.strokeWidth = strokeWidth; 
     topy = 2*radius; 
     bottomy = 3*radius; 
     curx = 2*radius; 
     cury = topy; 
     startAngleL = TOP_START_ANGLES[0]; 
     startAngleR = TOP_START_ANGLES[1]; 
     prevIndexL = 0; 
     prevIndexR = 0; 
    } 

    public void paintNextRing(Color color) { 
     addArcL(color); 
     addArcR(color); 
     advance(); 
    } 

    private void addArcL(Color color) { 
     Arc arcL = makeArc(startAngleL, color); 
     if(cury == topy) { 
      pane.getChildren().add(prevIndexL, arcL); 
     } 
     else { 
      pane.getChildren().add(prevIndexR, arcL); 
      prevIndexL = prevIndexR; 
     } 
    } 

    private void addArcR(Color color) { 
     Arc arcR = makeArc(startAngleR, color); 
     pane.getChildren().add(arcR); 
     prevIndexR = pane.getChildren().size() - 1; 
    } 

    private Arc makeArc(double startAngle, Color color) { 
     Arc arc = new Arc(curx, cury, radius, radius, startAngle, 180); 
     arc.setFill(null); 
     arc.setStroke(color); 
     arc.setStrokeWidth(strokeWidth); 
     return arc; 
    } 

    private void advance() { 
     curx += radius + strokeWidth; 
     if(cury == topy) { 
      cury = bottomy; 
      startAngleL = BOTTOM_START_ANGLES[0]; 
      startAngleR = BOTTOM_START_ANGLES[1]; 
     } 
     else { 
      cury = topy; 
      startAngleL = TOP_START_ANGLES[0]; 
      startAngleR = TOP_START_ANGLES[1]; 
     } 
    } 
} 

例使用法:

package olympicrings; 

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class OlympicRingsApplication extends Application { 

    public void start(Stage primaryStage) { 
     Pane pane = new Pane(); 
     OlympicRingsPaintingContext ctx = new OlympicRingsPaintingContext(pane, 50, 10); 
     OlympicRingsPaintingContext.STANDARD_OLYMPIC_COLORS.forEach(ctx::paintNextRing); 
// nobody stops you here though... 
//  ctx.paintNextRing(javafx.scene.paint.Color.AQUA); 

     Scene scene1 = new Scene(pane, 440, 250); // creates the parameters of the pane 
     primaryStage.setTitle("Olympic Rings"); // names the pane 
     primaryStage.setScene(scene1); // picks what will go in the pane 
     primaryStage.show(); // shows the scene i've created 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
関連する問題