英文:
JavaFx 2D, 3D, SVG Shapes
问题
关于下面的图片,我有一个普遍性的问题。我有点困惑如何使用JavaFX创建这样一个组件。下面船图的每个部分都像一个按钮一样起作用,而且可以根据“尺寸、颜色等”动态更改。
我不确定是否可以使用SVG路径或2D对象动态创建它,或者是否更好地使用类似于“.obj、.stl等”的2D-3D文件类型。
如果有人之前遇到过这种情况,欢迎留下答案和意见进行讨论。
英文:
I have a general question about the image below. I am a bit confused about how I can create such a component with JavaFX. Each division of the ship graphic below function as a button on itself also changes dynamically as: "dimensions colors etc".
I am not sure if this can be created dynamically with SVG Paths or 2D objects or it is better to use file 2D-3D file types like (".obj, .stl ... etc").
If anyone has been faced before with this situation is welcome to leave an answer and opinion to discuss it.
答案1
得分: 2
Answer Clarifier
当我第一次阅读您的问题时,我假设它是关于在您的问题中选择图像部分的,但也许不是,只是关于如何表示和绘制对象,而不涉及与其部分交互。如果不需要交互,您可以忽略答案中的选取部分,只看形状表示部分。
选取(Picking)
您可以通过多种方式实现所描述的结果。您尝试实现的技术术语是“选取”(picking),但除了选取之外,还有许多其他因素可能会影响您如何表示对象,以及您是使用2D还是3D系统,甚至JavaFX是否是您的应用程序的最合适框架。您可能需要一个3D系统,或者在您的情况下,2D系统可能足够(我不清楚)。
相关信息:
PickResult
来自链接的选取文章中的示例处理程序:
EventHandler<MouseEvent> moveHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
PickResult res = event.getPickResult();
// 对选取结果执行操作。
event.consume();
}
};
该选取文章使用了 PickResult
。PickResult 可以解释2D和3D信息。对于2D信息,通常只有所选节点相关。对于3D选取,它会提供附加信息,例如纹理坐标和选取的3D面。
诸如 setOnMouseClicked
的便利方法
通常在2D中,除了选择的节点之外,您不需要太多额外的信息。在这种情况下,您不需要查询和查看 PickResult 中的所有信息。您可以利用用户交互处理的 "便利方法",例如 setOnMouseClicked
。在所有节点上设置点击处理程序,您将能够在单击每个节点时执行相关的操作(类似于按钮的功能)。
对于不规则形状,您可能需要确保使用 setPickOnBounds(false)
。还要注意,如果 pick on bounds 设置为 false,并且您希要在不规则形状内注册点击事件,则该形状的内部必须填充有颜色(与您的图片不同)。如果需要,颜色可以是半透明的,但不能完全透明。这是因为如果您没有任何可点击的内容,点击事件将不会被注册。
悬停时绑定
参见这个问题的 smurf 回答,其中示例了当节点的悬停属性更改状态时如何执行操作。
实现自己的命中测试
当您在场景图中拥有节点时,您可以利用JavaFX内置的 命中测试 系统来进行选取关联。
另一种选择是在 Canvas 中渲染图像,而不使用场景图,然后实现自己的命中测试算法并使用它。这就是 trashgod 在以下问题的回答中所示的解决方案:
如果您在画布内使用 绘图算法 来渲染复杂的重叠形状,这可能会变得复杂。因此,我建议您在此任务中使用具有2D或3D形状的场景图,而不是使用画布。
形状表示
以下是您可以做到这一点的示例方式:
- 从3D数据文件导入的3D网格。
- 一组2D
SVGPaths
。 - 一组2D
Images
。
选择哪种表示取决于应用程序,因为某些表示方法对不同目的更合适。对于您在问题中显示的图像,似乎您拥有同一对象的各种正交投影,使用 ParallelCamera
将3D表示渲染到2D平面上可能是最好的选择。对于许多其他应用程序,位图2D图像是最佳选择。
要表示不规则的2D形状,您可以使用 SVGPath
,如果有适当的路径信息。如果没有适当的路径信息,您将很难使用2D系统来表示类似问题中的复杂图像集(即使有路径信息,对您来说也可能是具有挑战性的)。
形状表示的另一种选择是从像 PNG 这样的位图文件中读取的 Image
,这些文件具有透明背景,以便允许不规
英文:
Answer Clarifier
When I first read your question, I assumed it was about picking or selecting parts of the image in your question, but perhaps it is not and is only about how to represent and draw the object rather an interact with parts of it. If no interaction is required, you can ignore the picking portions of the answer and just look at the shape representation portion.
Picking
There are a variety of ways you could achieve the described results. The technical term for what you are trying to achieve is "picking", but there are a lot of things beyond picking which might influence how you represent your objects and, whether you use a 2D or 3D system and even whether JavaFX is the most appropriate framework for your application. You might need a 3D system, or a 2D system might suffice in your case (I don't know).
Related information:
PickResult
Sample handler from the linked picking article:
EventHandler<MouseEvent> moveHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
PickResult res = event.getPickResult();
// do something with the pick result.
event.consume();
}
}
That picking article uses a PickResult
. The PickResult can interpret both 2D and 3D information. In the case of 2D information, usually just the node picked is relevant. In the case of 3D picking it provides additional information such as texture co-ordinates and the 3D face picked.
Convenience methods such as setOnMouseClicked
Usually in 2D, you don't require a lot of additional information beyond which nodes have been selected. In this case, you don't need to query and look at all of the information in the PickResult. You can make use of the "convenience methods" for user interaction handling such as setOnMouseClicked
. Set a click handler on all of your nodes and you will be able to action each node as it is clicked (similar to how buttons function) via its related click handler.
For irregular shapes, you probably want to ensure you have setPickOnBounds(false)
. Also note that, if pick on bounds is false, and you want a click inside an irregular shape to register, the inside of the shape must be filled with a color (unlike in your picture). If necessary the color can be translucent, but not completely transparent. This is because if you don't have anything to click on, the click won't register.
Binding on hover
See the smurf answer to this question for an example of taking an action when the hover property of a node changes status.
Implementing your own hit-testing
When you have nodes in the scene graph, then you can make use of JavaFX in-built system of hit-testing for pick correlation.
Another alternative is to render your images within a Canvas without making use of the scene graph, and then implement your own hit-testing algorithm and use that. That is the solution illustrated in trashgod's answer to:
This can get complicated if you use a painter's algorithm to render complicated overlapping shapes within the canvas. Therefore, I'd recommend making use of the scene graph with either 2D or 3D shapes rather than using a canvas for this task.
Shape Representation
Sample ways you could do this:
- 3D meshes imported from 3D data files.
- Collections of 2D
SVGPaths
. - Collections of 2D
Images
.
Which representation to choose depends on the application as some will be better suited for different purposes. For the image you show in your question, where you appear to have various orthographic projections of the same object, using a ParallelCamera
to render 3D representations onto a 2D plane might be best. For many other applications, bitmapped 2D images are best.
To represent irregular 2D shapes you can use an SVGPath
if you have the appropriate path info. If you don't have the appropriate path info, it will be challenging for your to use a 2D system to represent a complex set of images like you have in your question (it will probably be challenging for you even with path info).
Another option for shape representation are Image
s read from bitmap files such as PNG which have transparent backgrounds to allow for irregular shapes.
Aside
This question is probably going to get closed as not focused enough, because that is just what happens to questions like this. This answer is similarly more general in scope rather than specific and, in particular, does not provide the complete code (or really any code at all) for you to implement a solution to the problem you outlined in your question.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论