我想画一个三维曲面的网格。根据选择的分辨率,曲面可能由数千个彼此相邻的多边形组成。
分辨率较低时,结果看起来不错。使用更高的分辨率,网格的网格线要么清晰可见,要么形成这种奇怪的斑马条纹效果(见图)。我希望有一个光滑的表面-我如何做到这一点?
我在Windows10机器上使用JavaFX和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条答案
按热度按时间d5vmydt91#
有两条路要走。对于低分辨率,你应该给瓷砖一点重叠。对于高分辨率,您可以更改算法并计算显式像素颜色,而不是使用多边形。另一种选择是使用三角形网格,而不是画布。