在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 中的点矩阵
  • 使用 HashMap 填充 TableView,该 HashMap 更改时将更新

    我已经关注这个帖子了 将 hashmap 与 tableview 绑定 JavaFX https stackoverflow com questions 18618653 binding hashmap with tableview jav
  • 如何理解JavaFX三角形网格?

    只是想了解有关三角形网格的 JavaFX 文档 这段代码可以工作并绘制一个矩形 public class Shape3DRectangle extends TriangleMesh public Shape3DRectangle float
  • 了解截断二十面体的几何形状,以进行渲染

    我正在尝试使用可点击区域来渲染像上面这样的截断二十面体Three js http stemkoski github io Three js js Three js 我找到了正二十面体的代码 var t 1 Math sqrt 5 2 var
  • 使用 Numpy 快速制作网格三角网格

    考虑一个表示编号节点的正则矩阵 如图所示 我想制作一个包含图中表示的所有三角形的列表 这将产生以下二维列表 0 1 4 1 5 4 1 2 5 2 6 5 11 15 14 假设矩阵的维度为 NrXNc 在本例中为 4X4 我可以使用以下代
  • 如何给 Git 控制台着色?

    我最近看到gitWindows 中的控制台是彩色的 例如绿色表示添加 红色表示删除等 我如何为我的颜色上色git这样的控制台 为了安装它 我使用了以下命令 sudo apt get install git core As noted htt
  • 从样条解的给定点数组中查找 3 维 B 样条控制点?

    佤族正在谈论非均匀有理 B 样条 http en wikipedia org wiki Non uniform rational B spline 我们有一些简单的 3 维数组 例如 1 1 1 1 2 3 1 3 3 2 4 5 2 5
  • 将颜色名称转换为十六进制代码的 Javascript 函数

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

    我所在的团队正在构建一个使用 JavaFX 8 3D 操作视觉模型的应用程序 我们同时使用透视相机和平行相机 透视相机按预期工作 目前正在与isEyeAtCameraZero错误的 这样做是为了最大限度地兼容并行相机 透视相机在以下情况下表
  • android 更改微调器中项目的文本颜色

    我有一个微调器 在某些情况下某些选项不应该被选择 我有使项目不可选择的代码 但它不会使文本颜色变灰以指定该项目不可选择 如何更改微调器中应禁用的项目的文本颜色 这是代码 public class main extends Activity
  • C# 应用程序广泛的色彩管理

    我正在编写一个大型 C 应用程序 要点是控件的颜色应该由应用程序的用户进行调整 如果有任何解决方案可以覆盖 仅适用于该应用程序的上下文 System Drawing SystemColors 那么我就不必手动设置每个控件的值 那就太好了 有
  • 确定对角线周围的边界矩形

    用户将在屏幕上定义一条线 绘制时该线将具有给定的粗细 or width I now need to be able to determine the coordinates of a bounding rectangle around th
  • JavaFX 本机捆绑包图标 OS X

    我正在尝试使用 IntelliJ IDEA 14 为 JavaFX 应用程序创建本机 OS X 应用程序包 我已经设置了一个 Artifact 并将本机包选项设置为 dmg 这确实创建了一个本机捆绑包 但我似乎找不到更改应用程序图标的方法
  • 将 svg 圆弧转换为直线

    我正在尝试将 SVG 弧转换为一系列线段 背景是 我想使用 reportlab 绘制弧线 http www reportlab com http www reportlab com 5D svg 给了我这些参数 根据here https d
  • 基于数组和颜色图对matplotlib背景进行着色

    我想知道是否可以根据绘制的数据对典型 matplotlib 图的背景进行着色 为了简单起见 假设我们有 x arange 1 5 0 01 y sin x plot x y 那么是否可以根据 y 值对轴的背景进行着色 可以通过将包含 x 和
  • 在javafx上为三角形网格中的各个三角形着色

    我在 JAVAFX 中有一个三角形网格对象 并且想要 为三角形网格的各个三角形着色 or 为每个三角形的各个顶点着色 并根据每个顶点颜色的插值 例如使用 Gouraud 阴影 对三角形进行着色 特定的三角形网格对象是一个具有数百万个面的 i
  • Android OpenGL .OBJ 文件加载器 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 人们似乎已经开发了很多在 Android 平台上使用的 OBJ 网格文件加载器 我想知道是否有人对这些有任何经验 并且可以提供最适合他们的
  • TableView 上的一行上下文菜单?

    我正在使用 JavaFX 我的应用程序有一个表 我可以向表中添加元素 但我想创建一个上下文菜单 当我右键单击该行时 该菜单会显示在该行上 我拥有的 在场景生成器中 我有一个在激活上下文菜单时运行的方法 但这并不是我想要的 这真的很好 因为我
  • JavaFx - tableView 中的 String 和 FlowPane (行?)?

    我目前正在尝试实现以下内容 一个以 ObservableList 作为数据集的 TableView 有两列 每列包含字符串 玩家的姓名 这部分很简单 单击播放器 名称 后 应在所选播放器下方注入自定义 FlowPane 如果单击另一个玩家
  • 如何在javafx中嵌入PApplet?

    所以我让我的处理代码在java中运行 但现在我想将它嵌入到我的 GUI 的 JavaFX 中 我怎样才能这样做呢 我尝试使用以下代码 但它似乎不起作用 package testprocessing import javafx applica

随机推荐