在javafx上为三角形网格中的各个三角形着色

2024-07-03

我在 JAVAFX 中有一个三角形网格对象,并且想要

  1. 为三角形网格的各个三角形着色

or

  1. 为每个三角形的各个顶点着色,并根据每个顶点颜色的插值(例如使用 Gouraud 阴影)对三角形进行着色。

特定的三角形网格对象是一个具有数百万个面的 icosphere(这就是我使用三角形网格的原因:我需要速度)。

我没有使用过纹理坐标,因为我无法使用 JAVAFX 找到它的清晰解释,而且我希望有一种更简单的方法。


JavaFX 3D 网格中的着色方式取决于您为其分配的材质。对于一个网格有一种材质,并且不可能将不同的材质分配给同一网格的不同三角形。

因此,如果你想避免纹理,恐怕唯一的方法是将具有相同颜色的三角形分组在同一网格中,并创建如此多的网格作为颜色。

相反,使用纹理相对容易......,因为您只有一个网格、一种材质和一张具有所有颜色的图像。

我做了一个二十面体的例子,建立了一个三角形mesh https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/TriangleMesh.html并添加了单个纹理来为所有面着色。

为此,我们需要:

  • 12 个顶点的 3D 坐标,
  • 纹理 uv 映射的 2D 归一化坐标。
  • 和20张脸。每个面由 6 个索引 p0、t0、p1、t1、p3、t3 定义,其中 p0、p1、p2 和 p3 是点数组的索引,t0、t1、t2 和 t3 是 texCoords 数组的索引。

    公共类二十面体网格扩展MeshView {

    public IcosahedronMesh(){
        setMesh(createCube());
    }
    private TriangleMesh createCube() {
        TriangleMesh m = new TriangleMesh();
    
        // POINTS
        m.getPoints().addAll(
            0f, 0f, -0.951057f, 
            0f, 0f, 0.951057f, 
            -0.850651f, 0f, -0.425325f, 
            0.850651f, 0f, 0.425325f, 
            0.688191f, -0.5f, -0.425325f, 
            0.688191f, 0.5f, -0.425325f, 
            -0.688191f, -0.5f, 0.425325f, 
            -0.688191f, 0.5f, 0.425325f, 
            -0.262866f, -0.809017f, -0.425325f, 
            -0.262866f, 0.809017f, -0.425325f, 
            0.262866f, -0.809017f, 0.425325f, 
            0.262866f, 0.809017f, 0.425325f
        );
    
        // TEXTURES
        m.getTexCoords().addAll(
                0.181818f, 0f, 
                0.363636f, 0f, 
                0.545455f, 0f, 
                0.727273f, 0f, 
                0.909091f, 0f,
                0.0909091f, 0.333333f,
                0.272727f, 0.333333f, 
                0.454545f, 0.333333f, 
                0.636364f, 0.333333f, 
                0.818182f, 0.333333f, 
                1f, 0.333333f, 
                0f, 0.666667f, 
                0.181818f, 0.666667f, 
                0.363636f, 0.666667f, 
                0.545455f, 0.666667f, 
                0.727273f, 0.666667f, 
                0.909091f, 0.666667f, 
                0.0909091f, 1f, 
                0.272727f, 1f, 
                0.454545f, 1f, 
                0.636364f, 1f, 
                0.818182f, 1f
        );
    
        // FACES
        m.getFaces().addAll(
                1, 6, 11, 5, 7, 0, 
                1, 12, 7, 11, 6, 5, 
                1, 7, 6, 6, 10, 1, 
                1, 13, 10, 12, 3, 6, 
                1, 8, 3, 7, 11, 2,
                4, 14, 8, 13, 0, 7, 
                5, 9, 4, 8, 0, 3, 
                9, 15, 5, 14, 0, 8, 
                2, 10, 9, 9, 0, 4, 
                8, 16, 2, 15, 0, 9,
                11, 5, 9, 6, 7, 12,
                7, 11, 2, 12, 6, 17, 
                6, 6, 8, 7, 10, 13, 
                10, 12, 4, 13, 3, 18, 
                3, 7, 5, 8, 11, 14,
                4, 13, 10, 14, 8, 19, 
                5, 8, 3, 9, 4, 15, 
                9, 14, 11, 15, 5, 20, 
                2, 9, 7, 10, 9, 16, 
                8, 15, 6, 16, 2, 21
        );
        return m;
    }
    

    }

现在我们需要一个基于二十面体网络的每个面都有颜色的图像,如下所示:

(图片找到here http://paulscottinfo.ipage.com/polyhedra/platonic/icosahedron/icosah_net.gif)

请注意,映射是从 (0,0) 到 (1,1) 标准化坐标到图像(左、上)到(右、下)像素完成的。

最后让我们创建场景,加载网格并将纹理添加到其材质中:

@Override
public void start(Stage primaryStage) throws Exception {
    Group sceneRoot = new Group();
    Scene scene = new Scene(sceneRoot, 600, 600, true, SceneAntialiasing.BALANCED);
    scene.setFill(Color.BLACK);
    PerspectiveCamera camera = new PerspectiveCamera(true);
    camera.setNearClip(0.1);
    camera.setFarClip(10000.0);
    camera.setTranslateZ(-4);
    scene.setCamera(camera);

    IcosahedronMesh mesh = new IcosahedronMesh();
    mesh.setCullFace(CullFace.FRONT);
    PhongMaterial mat = new PhongMaterial();
    mat.setDiffuseMap(new Image(getClass().getResourceAsStream("icosah_net.png")));
    mesh.setMaterial(mat);
    Rotate rotateY = new Rotate(0, 0, 0, 0, Rotate.Y_AXIS);
    mesh.getTransforms().addAll(new Rotate(30,Rotate.X_AXIS),rotateY);

    sceneRoot.getChildren().addAll(mesh, new AmbientLight(Color.WHITE));

    primaryStage.setTitle("JavaFX 3D - Icosahedron");
    primaryStage.setScene(scene);
    primaryStage.show();        
}

它是这样的:

EDIT

现在,如果您考虑如何应用纹理,您可以使用所需的颜色调色板将图像简化为几个正方形:

纹理坐标可以真正简化:

m.getTexCoords().addAll(
        0.1f, 0.5f, // 0 red
        0.3f, 0.5f, // 1 green
        0.5f, 0.5f, // 2 blue
        0.7f, 0.5f, // 3 yellow
        0.9f, 0.5f  // 4 orange
);

最后,我们必须将这些点映射到我们的脸上。遵循与网络图像相同的模式:

m.getFaces().addAll(
        1, 0, 11, 0, 7, 0, 
        1, 4, 7, 4, 6, 4, 
        1, 4, 6, 4, 10, 4, 
        1, 2, 10, 2, 3, 2, 
        1, 2, 3, 2, 11, 2,                
        4, 3, 8, 3, 0, 3, 
        5, 3, 4, 3, 0, 3, 
        9, 1, 5, 1, 0, 1, 
        2, 1, 9, 1, 0, 1, 
        8, 0, 2, 0, 0, 0, 

        11, 3, 9, 3, 7, 3,
        7, 1, 2, 1, 6, 1, 
        6, 1, 8, 1, 10, 1, 
        10, 0, 4, 0, 3, 0, 
        3, 0, 5, 0, 11, 0,

        4, 4, 10, 4, 8, 4, 
        5, 4, 3, 4, 4, 4, 
        9, 2, 11, 2, 5, 2, 
        2, 2, 7, 2, 9, 2, 
        8, 3, 6, 3, 2, 3
);

现在我们将得到一个非常整齐的二十面体,因为我们消除了图像的边框和不良分辨率:

这可以扩展到任何三角形网格,或使用任何算法 http://blog.andreaskahler.com/2009/06/creating-icosphere-mesh-in-code.html细化三角形。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在javafx上为三角形网格中的各个三角形着色 的相关文章

  • 给定三点计算仿射变换

    我有两张图像 并使用筛选找到了三个相似的二维点 我需要计算图像之间的仿射变换 不幸的是 我错过了讲座 而且那里的信息对我来说有点密集 计算这个 2x3 矩阵的一般方法是什么 我有 2x3 矩阵 x1 y1 x2 y2 x3 y3 中的点矩阵
  • 绘制圆圈(使用 for 循环在图像中应用的像素)

    我想使用像素位置 从左上角开始到右下角结束 绘制一个圆 带有 1 或 2 个 for 循环 我用这个方法成功绘制了一个矩形 private void drawrect int width int height int x int y int
  • JavaFX 图表自动缩放错误且数字较低

    我正在使用 JavaFX 构建 StackedBarChart 随着新数据的进入 图表将发生变化 我使用更新图表的按钮来模拟这一点 它大部分工作正常 但我注意到 当我第一次更新图表时 如果值较低 值小于 100 Y 轴标签似乎有点偏离 更奇
  • 检测霍夫圆android

    我正在尝试使用 android 检测圆圈 我成功实现了检测线算法 但在尝试绘制霍夫圆算法时没有显示任何内容 这是我的代码 Mat thresholdImage new Mat getFrameHeight getFrameHeight 2
  • JavaFX:使用 PathTransition 作为绘图笔的动画

    示例代码 node Rectangle rect new Rectangle 0 0 20 20 path Text text TextBuilder create text J a v a F X R o c k s font new F
  • 将颜色名称转换为十六进制代码的 Javascript 函数

    是否有一个内置函数可以将颜色按名称转换为其十六进制表示形式 就像我想传递 白色 并接收 FFFFFF 我真的想避免自己编写一百个 if 代码 不 但使用在这里列出 https www w3schools com colors colors
  • 如何使用 Javafx Canvas 绘制 1 像素线?

    我一直在谷歌搜索和搜索 发现了一些相关的问题 帖子 但没有一个能解决我的问题 我使用以下方法直接在画布 JavaFX 上绘制线条 gc setStroke color gc setLineWidth lineWidth gc strokeL
  • Java:作为 JAR 运行时的文件路径

    我有一个 Java JavaFX 项目 我在其中使用样式表 样式表中的图像将按如下方式加载 pane fx background image url packagename image jpg 当我从 Eclipse 或 Scenebuil
  • 如何创建具有同等时间元素的 JavaFX 转换?

    我正在尝试 JavaFX 和动画 尤其是PathTransition 我正在创建一个简单的程序 使球 弹跳 而不使用QuadCurveTo班级 到目前为止 这是我的代码 Ellipse ball new Ellipse 375 250 10
  • 找到给定点的最小面积矩形以计算长轴和短轴长度的算法

    I have a set of points black dots in geographic coordinate value derived from the convex hull blue of a polygon red see
  • Linux 上的 JavaFX

    Linux x86 和 x64 上的 JavaFX 情况如何 JavaFX 应用程序可以在 Linux 操作系统上顺利执行吗 我发现了 2011 年和 2012 年的一些问题 当时应用程序不稳定 目前发布的 JFX 版本是 2 2 4 在
  • jquery 按钮点击背景颜色变化

    为什么这不起作用 jquery button click function go css background color yellow html table tr td hello td table gt tr table
  • 使用线段树求矩形并集的面积

    我试图了解可用于计算一组轴对齐矩形的并集面积的算法 我遵循的解决方案在这里 http tryalgo org en geometry 2016 06 25 union of rectangles http tryalgo org en ge
  • Pygame - 两个圆圈的碰撞检测

    我正在制作一个碰撞检测程序 其中我的光标是一个半径为 20 的圆 当它碰到另一个圆时应该将值更改为 TRUE 出于测试目的 我在屏幕中心有一个半径为 50 的固定圆 我可以测试光标圆是否击中固定圆 但它不能正常工作 因为它实际上是在测试它是
  • 将 svg 圆弧转换为直线

    我正在尝试将 SVG 弧转换为一系列线段 背景是 我想使用 reportlab 绘制弧线 http www reportlab com http www reportlab com 5D svg 给了我这些参数 根据here https d
  • 如何在JavaFX中获得狭窄的进度条?

    正如标题所说 我需要制作一个细进度条 我用过这个 progressBar setMaxHeight 0 1 progressBar setPrefHeight 0 1 但这行不通 有人有想法吗 你必须搞乱样式才能让它变小 我真的建议看看ca
  • JavaFX ComboBox - 显示文本但在选择时返回 ID

    我有一个包含机场的数据库表 每个机场都有一个名称和一个 ID 在 JavaFX 中我有一个表单 其中包含ComboBox 组合框需要显示所有机场名称 并且在提交表单时需要将机场的 ID 插入数据库 而不是其名称 但我并没有真正弄清楚解决方案
  • 如何使用不同的fxml文件创建多个javafx控制器?

    我一直在查看一些博客和其他 stackoverflow 问题 但没有看到我的问题的直接答案 我正在创建一个 javafx gui 客户端 我希望我的菜单栏成为一个 fxml 中的一个控制器 然后我希望内容区域成为附加的 fxml 文件 登录
  • 光栅化和填充超球面的算法?

    我正在尝试光栅化并填充超球面 本质上 我有一个固定大小的 d 维网格和一个球体 中心 半径 并且想要找出网格的哪些单元格与球体重叠并存储它们的坐标 我知道中点圆算法 http en wikipedia org wiki Midpoint c
  • 如何在 CSS 中创建八角形蒙版

    我正在尝试创建一种图像形状为八角形的设计 我使用了边框破解 但图像需要位于八边形形状内 在这种情况下使用伪元素并不合适 因为主体也将有自己的背景图像 用css可以吗 My Code div width 100vh height 100vh

随机推荐