我希望有人可以帮助我解决这个问题。
我正在使用javafx和三角形网格从三角形(如橄榄球)中构造出类似球形的对象。形状不同的图块通过颜色区分,但是我想在图块之间添加线条。就像在这个足球比赛中一样:
提供的javafx 2D行在3D空间中带来了可怕的性能。 因此,我发现提供FXyzLib的PolyLine3D。实际上,这只是在3D空间中创建线的另一个三角形网格。
以此,我可以创建3D线。但是,如果我要将它们添加到我的原始三角形网格中,其他所有内容都会变黑。反之亦然。我尝试了提供的here找到的库示例。它会创建一条奇特的3D线,但是当我尝试向场景中添加一个简单的红色球体时,该球体就是黑色的,就像这样:
。
我不是这方面的专家,也不是javafx的新手,也无法在PolyLine3D的代码中找到问题。向场景中添加多个三角形网格应该不是问题。有我不知道的灯光或相机效果吗?
编辑:我解决了这个问题。 Polyline3D中使用的环境光导致了此问题。如果您为其他对象添加光,那应该没事。
答案 0 :(得分:2)
尽管向场景添加多个三角形网格没有任何问题,但是当您要从足球图片中创建像一个网格那样的网格时,有一种更直接的方法,因此您可以突出显示某些边缘,而不是全部边缘网格中的三角形。
可以使用将任何有效的闭合多边形作为面的PolygonMesh
来完成。
此实现已经存在于3DViewer项目中,该项目是开源的,可以在here中找到。有一个PolygonMeshView
控件可以呈现PolygonMesh
。
请注意,如果仅在项目中使用这两个类,则现在必须跳过细分网格。
此answer已经使用四边形网格渲染Box,而没有三角形网格的对角线边缘。
在内部,Polygon网格使用三角形网格,并在内部将您提供的多边形转换为三角形。
截二十面体网格
因此,我们可以执行类似的操作来生成truncated icosahedron的网格,这是我们可以用来生成简化足球模型的几何图形的名称。
它具有12个规则的五边形面,20个规则的六边形面和60个顶点。
我们需要这些顶点的3D坐标,纹理的2D坐标以及32个面中每一个的顶点和纹理的索引。
我已经使用免费的在线沙箱WolframCloud resource来检索这些值。
例如,您可以运行:
Flatten[PolyhedronData["TruncatedIcosahedron","VertexCoordinates"]//N]
获取顶点坐标列表:
Out[1]= {-0.16246,-2.11803,1.27598,-0.16246,2.11803,...}
然后,您可以得到面孔:
PolyhedronData["TruncatedIcosahedron","FaceIndices"]
Out[2]= {{53,11,24,23,9},{51,39,40,52,30},...}
最后,您需要纹理坐标和索引,并且可以通过icosahedron的网络进行检索:
PolyhedronData["TruncatedIcosahedron","Net"]
PolyhedronData["TruncatedIcosahedron","NetCoordinates"]
在这种情况下,您将获得32个面的2D坐标。鉴于我们希望所有五边形具有相同的纹理,并且所有六边形具有相同的纹理,我对这些坐标进行了一些操纵以得出该纹理图像:
只有9个顶点及其坐标(在JavaFX坐标系中)。
此方法包含创建网格所需的信息:
private PolygonMesh getTruncatedIcosahedron() {
float[] points = new float[]{
-0.16246f,-2.11803f,1.27598f, -0.16246f,2.11803f,1.27598f,
0.16246f,-2.11803f,-1.27598f, 0.16246f,2.11803f,-1.27598f,
-0.262866f,-0.809017f,-2.32744f, -0.262866f,-2.42705f,-0.425325f,
-0.262866f,0.809017f,-2.32744f, -0.262866f,2.42705f,-0.425325f,
0.262866f,-0.809017f,2.32744f, 0.262866f,-2.42705f,0.425325f,
0.262866f,0.809017f,2.32744f, 0.262866f,2.42705f,0.425325f,
0.688191f,-0.5f,-2.32744f, 0.688191f,0.5f,-2.32744f,
1.21392f,-2.11803f,0.425325f, 1.21392f,2.11803f,0.425325f,
-2.06457f,-0.5f,1.27598f, -2.06457f,0.5f,1.27598f,
-1.37638f,-1.f,1.80171f, -1.37638f,1.f,1.80171f,
-1.37638f,-1.61803f,-1.27598f, -1.37638f,1.61803f,-1.27598f,
-0.688191f,-0.5f,2.32744f, -0.688191f,0.5f,2.32744f,
1.37638f,-1.f,-1.80171f, 1.37638f,1.f,-1.80171f,
1.37638f,-1.61803f,1.27598f, 1.37638f,1.61803f,1.27598f,
-1.7013f,0.f,-1.80171f, 1.7013f,0.f,1.80171f,
-1.21392f,-2.11803f,-0.425325f, -1.21392f,2.11803f,-0.425325f,
-1.96417f,-0.809017f,-1.27598f, -1.96417f,0.809017f,-1.27598f,
2.06457f,-0.5f,-1.27598f, 2.06457f,0.5f,-1.27598f,
2.22703f,-1.f,-0.425325f, 2.22703f,1.f,-0.425325f,
2.38949f,-0.5f,0.425325f, 2.38949f,0.5f,0.425325f,
-1.11352f,-1.80902f,1.27598f, -1.11352f,1.80902f,1.27598f,
1.11352f,-1.80902f,-1.27598f, 1.11352f,1.80902f,-1.27598f,
-2.38949f,-0.5f,-0.425325f, -2.38949f,0.5f,-0.425325f,
-1.63925f,-1.80902f,0.425325f, -1.63925f,1.80902f,0.425325f,
1.63925f,-1.80902f,-0.425325f, 1.63925f,1.80902f,-0.425325f,
1.96417f,-0.809017f,1.27598f, 1.96417f,0.809017f,1.27598f,
0.850651f,0.f,2.32744f, -2.22703f,-1.f,0.425325f,
-2.22703f,1.f,0.425325f, -0.850651f,0.f,-2.32744f,
-0.525731f,-1.61803f,-1.80171f, -0.525731f,1.61803f,-1.80171f,
0.525731f,-1.61803f,1.80171f, 0.525731f,1.61803f,1.80171f};
float[] texCoords = new float[]{0.904508f,0.820298f, 0.75f,0.529535f, 0.25f,0.529535f, 0.0954915f,0.820298f, 0.5f,1f,
1f,0.264767f, 0.75f,0f, 0.25f,0f, 0f,0.264767f};
int faces[][] = new int[][]{{52,0,10,1,23,2,22,3,8,4},
{50,0,38,1,39,2,51,3,29,4},
{59,0,27,1,15,2,11,3,1,4},
{19,0,41,1,47,2,54,3,17,4},
{18,0,16,1,53,2,46,3,40,4},
{0,0,9,1,14,2,26,3,58,4},
{35,0,25,1,43,2,49,3,37,4},
{3,0,57,1,21,2,31,3,7,4},
{33,0,28,1,32,2,44,3,45,4},
{20,0,56,1,2,2,5,3,30,4},
{36,0,48,1,42,2,24,3,34,4},
{12,0,4,1,55,2,6,3,13,4},
{8,1,58,5,26,6,50,7,29,8,52,2},
{52,1,29,5,51,6,27,7,59,8,10,2},
{10,1,59,5,1,6,41,7,19,8,23,2},
{23,1,19,5,17,6,16,7,18,8,22,2},
{22,1,18,5,40,6,0,7,58,8,8,2},
{12,1,24,5,42,6,2,7,56,8,4,2},
{4,1,56,5,20,6,32,7,28,8,55,2},
{55,1,28,5,33,6,21,7,57,8,6,2},
{6,1,57,5,3,6,43,7,25,8,13,2},
{13,1,25,5,35,6,34,7,24,8,12,2},
{39,1,37,5,49,6,15,7,27,8,51,2},
{15,1,49,5,43,6,3,7,7,8,11,2},
{11,1,7,5,31,6,47,7,41,8,1,2},
{47,1,31,5,21,6,33,7,45,8,54,2},
{54,1,45,5,44,6,53,7,16,8,17,2},
{53,1,44,5,32,6,20,7,30,8,46,2},
{46,1,30,5,5,6,9,7,0,8,40,2},
{9,1,5,5,2,6,42,7,48,8,14,2},
{14,1,48,5,36,6,38,7,50,8,26,2},
{38,1,36,5,34,6,35,7,37,8,39,2}};
int[] smooth = new int[] {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32
};
PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
mesh.getFaceSmoothingGroups().addAll(smooth);
return mesh;
}
现在您可以轻松地将其添加到场景:
private double mouseOldX, mouseOldY = 0;
private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
@Override
public void start(Stage primaryStage) {
PolygonMeshView meshView = new PolygonMeshView(getTruncatedIcosahedron());
final PhongMaterial phongMaterial = new PhongMaterial();
meshView.setDrawMode(DrawMode.LINE);
meshView.setMaterial(phongMaterial);
final Group group = new Group(meshView);
group.getTransforms().add(new Scale(50, 50, 50));
Scene scene = new Scene(group, 500, 300, true, SceneAntialiasing.BALANCED);
scene.setOnMousePressed(event -> {
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setNearClip(0.1);
camera.setFarClip(1000.0);
camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0));
scene.setCamera(camera);
primaryStage.setTitle("JavaFX 3D - Truncated Icosahedron");
primaryStage.setScene(scene);
primaryStage.show();
}
将为您提供线框:
如果添加纹理图像,您将获得足球:
phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("net3.png")));
meshView.setDrawMode(DrawMode.FILL);
现在,您可以根据自己的喜好来操纵此信息,然后将此网格修改为您要查找的网格。