当前位置: 首页 > 知识库问答 >
问题:

JavaFX画布fillPolygon方法不能创建光滑的表面(网格线可见)

华景焕
2023-03-14

我想绘制一个三维表面的网格。根据所选择的分辨率,曲面可能由成千上万个彼此相邻的多边形组成。

在低分辨率下,结果看起来很好。使用更高的分辨率,网格网格的网格线要么清晰可见和/或形成这种奇怪的斑马条纹效果(见图)。我想有一个光滑的表面-我如何实现这一点?

我在Windows10机器上使用java fx、Java1.8。抗锯齿作用。

最小示例:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.DepthTest;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

import static javafx.scene.SceneAntialiasing.BALANCED;

public class MeshGridTest extends Application {


    @Override
    public void start(Stage primaryStage) throws Exception {
        try {

            primaryStage.setTitle("3D test");
            VBox root = new VBox();
            root.setDepthTest(DepthTest.ENABLE);
            root.setSpacing(10);
            HBox graphBox = new HBox();
            graphBox.setSpacing(10);
            graphBox.setPadding(new Insets(20, 20, 20, 20));
            root.getChildren().add(graphBox);
                        double canvasWidth = 500;
            double canvasHeight = 500;
            Canvas canvas = new Canvas(canvasWidth, canvasHeight);
            GraphicsContext context = canvas.getGraphicsContext2D();
            graphBox.getChildren().add(canvas);
            context.setFill(Color.web("0x4683b4ff"));
            context.fillPolygon(new double[]{79.38458612953876, 115.1333465737948, 124.35915222707138, 90.07817382229237}, new double[]{453.7674972431933, 453.62365127662974, 425.38481745205695, 425.3658453584012}, 4);
            context.setFill(Color.web("0x4685b5ff"));
            context.fillPolygon(new double[]{90.07817382229237, 124.35915222707138, 132.7123083001136, 99.6559534108369}, new double[]{425.3658453584012, 425.38481745205695, 399.1086555987629, 398.6272838484313}, 4);
            context.setFill(Color.web("0x458cb7ff"));
            context.fillPolygon(new double[]{99.6559534108369, 132.7123083001136, 139.89481376635175, 108.21467522318329}, new double[]{398.6272838484313, 399.1086555987629, 373.0866916804024, 373.0987504772544}, 4);
            context.setFill(Color.web("0x449bbbff"));
            context.fillPolygon(new double[]{108.21467522318329, 139.89481376635175, 145.98680660267343, 116.07375278278231}, new double[]{373.0987504772544, 373.0866916804024, 346.7109974406283, 349.12352586863017}, 4);
            context.setFill(Color.web("0x43afc2ff"));
            context.fillPolygon(new double[]{116.07375278278231, 145.98680660267343, 151.48043135860547, 123.13660694768703}, new double[]{349.12352586863017, 346.7109974406283, 321.0970002825233, 325.9076627857052}, 4);
            context.setFill(Color.web("0x41cccaff"));
            context.fillPolygon(new double[]{123.13660694768703, 151.48043135860547, 156.24933314601532, 129.30559799734607}, new double[]{325.9076627857052, 321.0970002825233, 295.24566224164175, 302.56790228993924}, 4);
            context.setFill(Color.web("0x65e6a8ff"));
            context.fillPolygon(new double[]{129.30559799734607, 156.24933314601532, 160.48424463177454, 134.57141212068763}, new double[]{302.56790228993924, 295.24566224164175, 269.4538308385731, 278.4751392714206}, 4);
            context.setFill(Color.web("0xbef547ff"));
            context.fillPolygon(new double[]{134.57141212068763, 160.48424463177454, 164.75351382381356, 139.19371903623178}, new double[]{278.4751392714206, 269.4538308385731, 246.0112935309454, 254.08862228739235}, 4);
            context.setFill(Color.web("0xfcec05ff"));
            context.fillPolygon(new double[]{139.19371903623178, 164.75351382381356, 169.36621372437594, 143.79263195686968}, new double[]{254.08862228739235, 246.0112935309454, 226.49445381500652, 231.64655982045508}, 4);
            context.setFill(Color.web("0xf2a916ff"));
            context.fillPolygon(new double[]{143.79263195686968, 169.36621372437594, 174.16498122336426, 148.7643186047649}, new double[]{231.64655982045508, 226.49445381500652, 210.33952100887984, 212.92380031415433}, 4);
            context.setFill(Color.web("0xed851fff"));
            context.fillPolygon(new double[]{148.7643186047649, 174.16498122336426, 178.94141300708233, 153.97544571540766}, new double[]{212.92380031415433, 210.33952100887984, 196.5379776965533, 197.53566928262848}, 4);
            context.setFill(Color.web("0xeb7922ff"));
            context.fillPolygon(new double[]{153.97544571540766, 178.94141300708233, 183.60324212961166, 159.19501673676973}, new double[]{197.53566928262848, 196.5379776965533, 184.53843497120874, 184.49494238828652}, 4);
            context.setFill(Color.web("0xec7d21ff"));
            context.fillPolygon(new double[]{159.19501673676973, 183.60324212961166, 188.1222449453474, 164.31197932847522}, new double[]{184.49494238828652, 184.53843497120874, 174.0815042668034, 173.23165438552195}, 4);
            context.setFill(Color.web("0x4685b5ff"));
            context.fillPolygon(new double[]{115.1333465737948, 150.71187770617652, 158.54986477004223, 124.35915222707138}, new double[]{453.62365127662974, 452.87242944863726, 425.09186653322604, 425.38481745205695}, 4);
            context.setFill(Color.web("0x4684b5ff"));
            context.fillPolygon(new double[]{124.35915222707138, 158.54986477004223, 165.60012074939144, 132.7123083001136}, new double[]{425.38481745205695, 425.09186653322604, 399.13379390423444, 399.1086555987629}, 4);
            context.setFill(Color.web("0x4689b6ff"));
            context.fillPolygon(new double[]{132.7123083001136, 165.60012074939144, 171.83179206641202, 139.89481376635175}, new double[]{399.1086555987629, 399.13379390423444, 374.1380223021333, 373.0866916804024}, 4);
            context.setFill(Color.web("0x449ebcff"));
            context.fillPolygon(new double[]{139.89481376635175, 171.83179206641202, 176.37561763303003, 145.98680660267343}, new double[]{373.0866916804024, 374.1380223021333, 345.4595014888617, 346.7109974406283}, 4);
            context.setFill(Color.web("0x42c6c8ff"));
            context.fillPolygon(new double[]{145.98680660267343, 176.37561763303003, 179.8481291080601, 151.48043135860547}, new double[]{346.7109974406283, 345.4595014888617, 314.4761503856426, 321.0970002825233}, 4);
            context.setFill(Color.web("0x69e7a3ff"));
            context.fillPolygon(new double[]{151.48043135860547, 179.8481291080601, 183.43079510430246, 156.24933314601532}, new double[]{321.0970002825233, 314.4761503856426, 286.2041149914594, 295.24566224164175}, 4);
            context.setFill(Color.web("0xc7f63dff"));
            context.fillPolygon(new double[]{156.24933314601532, 183.43079510430246, 187.26474778731273, 160.48424463177454}, new double[]{295.24566224164175, 286.2041149914594, 261.5075468958896, 269.4538308385731}, 4);
            context.setFill(Color.web("0xfbe307ff"));
            context.fillPolygon(new double[]{160.48424463177454, 187.26474778731273, 191.429026916089, 164.75351382381356}, new double[]{269.4538308385731, 261.5075468958896, 241.07103437098476, 246.0112935309454}, 4);
            context.setFill(Color.web("0xf1a218ff"));
            context.fillPolygon(new double[]{164.75351382381356, 191.429026916089, 195.73191191102035, 169.36621372437594}, new double[]{246.0112935309454, 241.07103437098476, 224.04785133565588, 226.49445381500652}, 4);
            context.setFill(Color.web("0xec8120ff"));
            context.fillPolygon(new double[]{169.36621372437594, 195.73191191102035, 199.9890645613384, 174.16498122336426}, new double[]{226.49445381500652, 224.04785133565588, 209.4004803784452, 210.33952100887984}, 4);
            context.setFill(Color.web("0xea7523ff"));
            context.fillPolygon(new double[]{174.16498122336426, 199.9890645613384, 204.12598154456248, 178.94141300708233}, new double[]{210.33952100887984, 209.4004803784452, 196.5919823216396, 196.5379776965533}, 4);
            context.setFill(Color.web("0xeb7922ff"));
            context.fillPolygon(new double[]{178.94141300708233, 204.12598154456248, 208.12453341832259, 183.60324212961166}, new double[]{196.5379776965533, 196.5919823216396, 185.38471553938376, 184.53843497120874}, 4);
            context.setFill(Color.web("0xed891eff"));
            context.fillPolygon(new double[]{183.60324212961166, 208.12453341832259, 211.95491329506487, 188.1222449453474}, new double[]{184.53843497120874, 185.38471553938376, 175.43384846181, 174.0815042668034}, 4);
            context.setFill(Color.web("0x458bb7ff"));
            context.fillPolygon(new double[]{150.71187770617652, 186.20520457333257, 192.43693191487066, 158.54986477004223}, new double[]{452.87242944863726, 451.40158648950126, 423.30893247464667, 425.09186653322604}, 4);
            context.setFill(Color.web("0x4689b6ff"));
            context.fillPolygon(new double[]{158.54986477004223, 192.43693191487066, 198.3196325771089, 165.60012074939144}, new double[]{425.09186653322604, 423.30893247464667, 398.36168724188406, 399.13379390423444}, 4);
            context.setFill(Color.web("0x4689b6ff"));
            context.fillPolygon(new double[]{165.60012074939144, 198.3196325771089, 203.4713843577531, 171.83179206641202}, new double[]{399.13379390423444, 398.36168724188406, 374.16895900242207, 374.1380223021333}, 4);
            context.setFill(Color.web("0x449bbbff"));
            context.fillPolygon(new double[]{171.83179206641202, 203.4713843577531, 207.50759808149047, 176.37561763303003}, new double[]{374.1380223021333, 374.16895900242207, 347.73356292823, 345.4595014888617}, 4);
            context.setFill(Color.web("0x41d4cdff"));
            context.fillPolygon(new double[]{176.37561763303003, 207.50759808149047, 209.14942590283852, 179.8481291080601}, new double[]{345.4595014888617, 347.73356292823, 310.12132358101934, 314.4761503856426}, 4);
            context.setFill(Color.web("0xb8f44dff"));
            context.fillPolygon(new double[]{179.8481291080601, 209.14942590283852, 211.61998483284617, 183.43079510430246}, new double[]{314.4761503856426, 310.12132358101934, 279.05112718572633, 286.2041149914594}, 4);
            context.setFill(Color.web("0xfade08ff"));
            context.fillPolygon(new double[]{183.43079510430246, 211.61998483284617, 215.12094526034042, 187.26474778731273}, new double[]{286.2041149914594, 279.05112718572633, 256.8461541054689, 261.5075468958896}, 4);
            context.setFill(Color.web("0xf09c19ff"));
            context.fillPolygon(new double[]{187.26474778731273, 215.12094526034042, 218.8194681929901, 191.429026916089}, new double[]{261.5075468958896, 256.8461541054689, 238.761242536079, 241.07103437098476}, 4);
            context.setFill(Color.web("0xec7c21ff"));
            context.fillPolygon(new double[]{191.429026916089, 218.8194681929901, 222.4678741782185, 195.73191191102035}, new double[]{241.07103437098476, 238.761242536079, 223.16290234376424, 224.04785133565588}, 4);
            context.setFill(Color.web("0xea7124ff"));
            context.fillPolygon(new double[]{195.73191191102035, 222.4678741782185, 225.9990616732908, 199.9890645613384}, new double[]{224.04785133565588, 223.16290234376424, 209.46224715829078, 209.4004803784452}, 4);
            context.setFill(Color.web("0xea7523ff"));
            context.fillPolygon(new double[]{199.9890645613384, 225.9990616732908, 229.40196475309995, 204.12598154456248}, new double[]{209.4004803784452, 209.46224715829078, 197.4313445122899, 196.5919823216396}, 4);
            context.setFill(Color.web("0xed851fff"));
            context.fillPolygon(new double[]{204.12598154456248, 229.40196475309995, 232.65760583289082, 208.12453341832259}, new double[]{196.5919823216396, 197.4313445122899, 186.7564306066988, 185.38471553938376}, 4);

            primaryStage.setScene(new Scene(root, 500, 500, true, BALANCED));
            primaryStage.show();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

共有1个答案

平和雅
2023-03-14

有两条路可走。对于低分辨率,您应该给瓷砖一点重叠。对于高分辨率,您可以更改算法,计算显式像素颜色,而不是使用多边形。另一个选择是使用TriangleMesh来代替画布。

 类似资料:
  • 我的javaFX项目中有一辆汽车,当空间被挤压时,汽车(节点)的位置应该改变(汽车应该平滑地跳跃)。所以我使用了一个事件处理程序来调用一个名为< code>moveUp()的方法 这创建了一个新的线程,其中汽车的速度以75毫秒的间隔改变10次。 如果我不使用其他线程,GUI线程将被冻结,如果我不使用Thread.sleep(),汽车将突然跳跃(不顺利)。这段代码做得很好。但是我了解到 并不能保证线

  • 本文向大家介绍C#画笔Pen绘制光滑模式曲线的方法,包括了C#画笔Pen绘制光滑模式曲线的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了C#画笔Pen绘制光滑模式曲线的方法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的C#程序设计有所帮助。

  • 我是一个Java/JavaFX程序员新手,我正在开发一个简单的JavaFX建筑设计工具,在这个工具中,您可以画出墙壁、地板等,因此对象(主要是线、圆、多边形、矩形图像)是在屏幕上绘制和创建的,而不是在运行之前创建的。

  • 我正在考虑将我们内部的汽车/测量应用程序从Swing移植到JavaFX,主要是因为它有更好的外观和多点触控支持,但是我找不到一种方法来渲染只有当它们可见时才可以呈现的自定义组件。 为了获得动力,想象一个有10个选项卡的屏幕,每个选项卡内都有一个显示正在测量的一些实时数据的图。任何时候,只能看到一个情节。数据量很大,计算机有足够的能力一次渲染一个情节,但不能同时渲染所有情节。 摇摆版 现在在Swin

  • 创建一个Canvas画布,用于显示WebGL的渲染结果,canvas元素和div等元素一样是HTML的一个元素,只是Canvas画布具有2D和3D绘图功能。 <!--canvas标签创建一个宽高均为500像素,背景为蓝色的矩形画布--> <canvas id="webgl" width="500" height="500" style="background-color: blue"></canv

  • 5.2.2 创建画布 为了绘图,首先要有画布。Tkinter 中提供了画布(Canvas),可以在画布上绘制图形、 文本,也可以在上面放置命令按钮等 GUI 构件。画布实际上是一个 Canvas 对象,它包含 一些属性(如画布的高度、宽度、背景色等),也包含一些方法(如在画布上创建图形、删 除或移动图形等)。 创建画布对象的语句模板如下: c = Canvas(<窗口>,<选项 1>=<值 1>,