微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaFX Canvas fillPolygon 方法不会创建平滑表面网格线可见

如何解决JavaFX Canvas fillPolygon 方法不会创建平滑表面网格线可见

我想绘制一个 3d 表面的网格。根据所选的分辨率,表面可能由数千个彼此相邻的多边形组成。

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

enter image description here

我在 Windows 10 机器上使用 java fx、java 1.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));
            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,132.7123083001136,99.6559534108369},new double[]{425.3658453584012,399.1086555987629,398.6272838484313},4);
            context.setFill(Color.web("0x458cb7ff"));
            context.fillpolygon(new double[]{99.6559534108369,139.89481376635175,108.21467522318329},new double[]{398.6272838484313,373.0866916804024,373.0987504772544},4);
            context.setFill(Color.web("0x449bbbff"));
            context.fillpolygon(new double[]{108.21467522318329,145.98680660267343,116.07375278278231},new double[]{373.0987504772544,346.7109974406283,349.12352586863017},4);
            context.setFill(Color.web("0x43afc2ff"));
            context.fillpolygon(new double[]{116.07375278278231,151.48043135860547,123.13660694768703},new double[]{349.12352586863017,321.0970002825233,325.9076627857052},4);
            context.setFill(Color.web("0x41cccaff"));
            context.fillpolygon(new double[]{123.13660694768703,156.24933314601532,129.30559799734607},new double[]{325.9076627857052,295.24566224164175,302.56790228993924},4);
            context.setFill(Color.web("0x65e6a8ff"));
            context.fillpolygon(new double[]{129.30559799734607,160.48424463177454,134.57141212068763},new double[]{302.56790228993924,269.4538308385731,278.4751392714206},4);
            context.setFill(Color.web("0xbef547ff"));
            context.fillpolygon(new double[]{134.57141212068763,164.75351382381356,139.19371903623178},new double[]{278.4751392714206,246.0112935309454,254.08862228739235},4);
            context.setFill(Color.web("0xfcec05ff"));
            context.fillpolygon(new double[]{139.19371903623178,169.36621372437594,143.79263195686968},new double[]{254.08862228739235,226.49445381500652,231.64655982045508},4);
            context.setFill(Color.web("0xf2a916ff"));
            context.fillpolygon(new double[]{143.79263195686968,174.16498122336426,148.7643186047649},new double[]{231.64655982045508,210.33952100887984,212.92380031415433},4);
            context.setFill(Color.web("0xed851fff"));
            context.fillpolygon(new double[]{148.7643186047649,178.94141300708233,153.97544571540766},new double[]{212.92380031415433,196.5379776965533,197.53566928262848},4);
            context.setFill(Color.web("0xeb7922ff"));
            context.fillpolygon(new double[]{153.97544571540766,183.60324212961166,159.19501673676973},new double[]{197.53566928262848,184.53843497120874,184.49494238828652},4);
            context.setFill(Color.web("0xec7d21ff"));
            context.fillpolygon(new double[]{159.19501673676973,188.1222449453474,164.31197932847522},new double[]{184.49494238828652,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,165.60012074939144,132.7123083001136},new double[]{425.38481745205695,399.13379390423444,399.1086555987629},4);
            context.setFill(Color.web("0x4689b6ff"));
            context.fillpolygon(new double[]{132.7123083001136,171.83179206641202,139.89481376635175},new double[]{399.1086555987629,374.1380223021333,373.0866916804024},4);
            context.setFill(Color.web("0x449ebcff"));
            context.fillpolygon(new double[]{139.89481376635175,176.37561763303003,145.98680660267343},new double[]{373.0866916804024,345.4595014888617,346.7109974406283},4);
            context.setFill(Color.web("0x42c6c8ff"));
            context.fillpolygon(new double[]{145.98680660267343,179.8481291080601,151.48043135860547},new double[]{346.7109974406283,314.4761503856426,321.0970002825233},4);
            context.setFill(Color.web("0x69e7a3ff"));
            context.fillpolygon(new double[]{151.48043135860547,183.43079510430246,156.24933314601532},new double[]{321.0970002825233,286.2041149914594,295.24566224164175},4);
            context.setFill(Color.web("0xc7f63dff"));
            context.fillpolygon(new double[]{156.24933314601532,187.26474778731273,160.48424463177454},new double[]{295.24566224164175,261.5075468958896,269.4538308385731},4);
            context.setFill(Color.web("0xfbe307ff"));
            context.fillpolygon(new double[]{160.48424463177454,191.429026916089,164.75351382381356},new double[]{269.4538308385731,241.07103437098476,246.0112935309454},4);
            context.setFill(Color.web("0xf1a218ff"));
            context.fillpolygon(new double[]{164.75351382381356,195.73191191102035,169.36621372437594},new double[]{246.0112935309454,224.04785133565588,226.49445381500652},4);
            context.setFill(Color.web("0xec8120ff"));
            context.fillpolygon(new double[]{169.36621372437594,199.9890645613384,174.16498122336426},new double[]{226.49445381500652,209.4004803784452,210.33952100887984},4);
            context.setFill(Color.web("0xea7523ff"));
            context.fillpolygon(new double[]{174.16498122336426,204.12598154456248,178.94141300708233},new double[]{210.33952100887984,196.5919823216396,196.5379776965533},4);
            context.setFill(Color.web("0xeb7922ff"));
            context.fillpolygon(new double[]{178.94141300708233,208.12453341832259,183.60324212961166},new double[]{196.5379776965533,185.38471553938376,184.53843497120874},4);
            context.setFill(Color.web("0xed891eff"));
            context.fillpolygon(new double[]{183.60324212961166,211.95491329506487,188.1222449453474},new double[]{184.53843497120874,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,198.3196325771089,165.60012074939144},new double[]{425.09186653322604,398.36168724188406,399.13379390423444},4);
            context.setFill(Color.web("0x4689b6ff"));
            context.fillpolygon(new double[]{165.60012074939144,203.4713843577531,171.83179206641202},new double[]{399.13379390423444,374.16895900242207,374.1380223021333},4);
            context.setFill(Color.web("0x449bbbff"));
            context.fillpolygon(new double[]{171.83179206641202,207.50759808149047,176.37561763303003},new double[]{374.1380223021333,347.73356292823,345.4595014888617},4);
            context.setFill(Color.web("0x41d4cdff"));
            context.fillpolygon(new double[]{176.37561763303003,209.14942590283852,179.8481291080601},new double[]{345.4595014888617,310.12132358101934,314.4761503856426},4);
            context.setFill(Color.web("0xb8f44dff"));
            context.fillpolygon(new double[]{179.8481291080601,211.61998483284617,183.43079510430246},new double[]{314.4761503856426,279.05112718572633,286.2041149914594},4);
            context.setFill(Color.web("0xfade08ff"));
            context.fillpolygon(new double[]{183.43079510430246,215.12094526034042,187.26474778731273},new double[]{286.2041149914594,256.8461541054689,261.5075468958896},4);
            context.setFill(Color.web("0xf09c19ff"));
            context.fillpolygon(new double[]{187.26474778731273,218.8194681929901,191.429026916089},new double[]{261.5075468958896,238.761242536079,241.07103437098476},4);
            context.setFill(Color.web("0xec7c21ff"));
            context.fillpolygon(new double[]{191.429026916089,222.4678741782185,195.73191191102035},new double[]{241.07103437098476,223.16290234376424,224.04785133565588},4);
            context.setFill(Color.web("0xea7124ff"));
            context.fillpolygon(new double[]{195.73191191102035,225.9990616732908,199.9890645613384},new double[]{224.04785133565588,209.46224715829078,209.4004803784452},4);
            context.setFill(Color.web("0xea7523ff"));
            context.fillpolygon(new double[]{199.9890645613384,229.40196475309995,204.12598154456248},new double[]{209.4004803784452,197.4313445122899,196.5919823216396},4);
            context.setFill(Color.web("0xed851fff"));
            context.fillpolygon(new double[]{204.12598154456248,232.65760583289082,208.12453341832259},new double[]{196.5919823216396,186.7564306066988,185.38471553938376},4);

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

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

解决方法

有两种方法。对于低分辨率,您应该给瓷砖一点重叠。对于高分辨率,您可以更改算法并计算显式像素颜色,而不是使用多边形。另一种选择是为此使用 TriangleMesh 而不是 Canvas。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。