Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaFX奥林匹克五环以正确的顺序重叠_Java_Javafx - Fatal编程技术网

JavaFX奥林匹克五环以正确的顺序重叠

JavaFX奥林匹克五环以正确的顺序重叠,java,javafx,Java,Javafx,这是我第一次在这里发帖。我目前正在做一项作业,我需要在JavaFX中创建奥运五环,并使它们在正确的位置相交 这就是它应该看起来的样子: 资料来源: 目前,环相交,但它们以我创建对象的顺序占主导地位。蓝色在相交时被黄色覆盖,黄色在相交时被黑色覆盖,等等。正如你在奥运五环图片中看到的,黄色和蓝色第一次相交时,黄色覆盖蓝色,但蓝色第二次覆盖黄色。每个环在相交时都会被另一个环覆盖,但在另一个环上会被覆盖 如果有人能给我指出正确的方向,让它们正确相交,那就太棒了 以下是我目前掌握的代码: package

这是我第一次在这里发帖。我目前正在做一项作业,我需要在JavaFX中创建奥运五环,并使它们在正确的位置相交

这就是它应该看起来的样子:

资料来源:

目前,环相交,但它们以我创建对象的顺序占主导地位。蓝色在相交时被黄色覆盖,黄色在相交时被黑色覆盖,等等。正如你在奥运五环图片中看到的,黄色和蓝色第一次相交时,黄色覆盖蓝色,但蓝色第二次覆盖黄色。每个环在相交时都会被另一个环覆盖,但在另一个环上会被覆盖

如果有人能给我指出正确的方向,让它们正确相交,那就太棒了

以下是我目前掌握的代码:

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
    }
}

这很难用圆圈来实现。这将大量使用clip属性,并且生成的代码不容易读取

取而代之的是可以用来画环的一部分。在添加覆盖部分之前,只需将环的覆盖部分添加到母环

前两个环的示例:

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();
}

谢谢你的提问,我很高兴提出了以下解决方案,请参阅Javadocs了解算法:

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];
        }
    }
}
*/ 公共类奥林匹克绘画背景{ /** *一个包含标准奥运会颜色的方便常数。可按如下方式使用 *要绘制标准的奥运五环: * */ 公共静态最终列表标准\u OLYMPIC\u COLORS=Collections.unmodifiableListArrays.asListColor.BLUE、Color.YELLOW、Color.BLACK、Color.GREEN、Color.RED; 私有静态最终双[]顶部开始角度=新双[]{45225}; 私有静态最终双[]底_开始_角度=新双[]{315135}; 专用窗格; 私人双半径; 私人双冲程宽度; 私人双重宵禁; 私人双槽; 私人双主题; 私人双底; 私人双星; 私人双星; 私人int prevIndexL; 私人int prevIndexR; public OlympicRingsPaintingContextPane窗格,双半径,双笔划宽度{ this.pane=窗格; 这个半径=半径; this.strokeWidth=strokeWidth; topy=2*半径; 底部=3*半径; curx=2*半径; cury=topy; startAngleL=顶部角度[0]; startAngleR=顶角、起始角[1]; prevIndexL=0; prevIndexR=0; } 公共空白颜料颜色{ 阿达色; 加大色; 进展 } 专用空白添加颜色{ Arc arcL=生成ArcStartAnglel,颜色; 如果cury==topy{ pane.getChildren.addprevIndexL,arcL; } 否则{ pane.getChildren.addprevIndexR,arcL; prevIndexL=prevIndexR; } } 专用空白添加颜色{ Arc arcR=makeArcstartAngleR,颜色; pane.getChildren.addarcR; prevIndexR=pane.getChildren.size-1; } 私人电弧makeArcdouble startAngle,彩色{ Arc Arc=新的Arccurx,cury,半径,半径,startAngle,180; arc.setFillnull; 弧度;设置行程颜色; 弧设置行程宽度行程宽度; 返回弧; } 私人无效预付款{ curx+=半径+冲程宽度; 如果cury==topy{ cury=底部; startAngleL=底部角度[0]; startAngleR=底部开始角度[1]; } 否则{ cury=topy; startAngleL=顶部角度[0]; startAngleR=顶角、起始角[1]; } } } 用法示例:


我不相信这是可能的使用圆圈单独。也许通过使用一些圆,而不是整个圆,你就能完成这个任务?谢谢!我能找出剩下的弧,这真的很有效。你介意帮我确切地了解顶级构造函数是如何工作的吗?我发现我们创建了一个返回Arc的构造函数,然后在Start类中不断调用该构造函数以利用它。我不知道构造函数正下方的那条线是做什么的,它以Arc=new Arc开头。为什么我们要列出两次半径,为什么我们有一条线是从角度到角度的,而不是绘制笔划?很抱歉,如果这很难理解的话,我正试着把我的头绕到这里。@TomBombadil您可以在这里的javadoc中找到描述:圆弧允许您绘制椭圆形,对于圆的特殊情况,我们有radiusX==radiusY。顺便说一句,createArc不是一个构造函数,它是一个方法。构造函数没有返回类型,只能用于创建包含类的实例。
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);
    }
}