在由大 Point3f 数组组成的 shape3D 中移动单个 Point3f
move individual Point3f in shape3D consisting of big Point3f array
我有以下代码在 canvas3D 中绘制 4 个点 window
public final class energon extends JPanel {
int s = 0, count = 0;
public energon() {
setLayout(new BorderLayout());
GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D(gc);//See the added gc? this is a preferred config
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
scene.compile();
// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
// This moves the ViewPlatform back a bit so the
// objects in the scene can be viewed.
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
}
public BranchGroup createSceneGraph() {
BranchGroup lineGroup = new BranchGroup();
Appearance app = new Appearance();
ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f, 204.0f), ColoringAttributes.SHADE_FLAT);
app.setColoringAttributes(ca);
Point3f[] plaPts = new Point3f[4];
for (int i = 0; i < 2; i++) {
for (int j = 0; j <2; j++) {
plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
//Look up line, i and j are divided by 10.0f to be able to
//see the points inside the view screen
count++;
}
}
PointArray pla = new PointArray(4, GeometryArray.COORDINATES);
pla.setCoordinates(0, plaPts);
Shape3D plShape = new Shape3D(pla, app);
TransformGroup objRotate = new TransformGroup();
objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRotate.addChild(plShape);
lineGroup.addChild(objRotate);
return lineGroup;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new JScrollPane(new energon()));
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
现在我想添加一个定时任务,定期更新 plaPts Point3f 数组中的一个点的位置。然而,当我调用 plaPts[1].setX(2) 时,屏幕上没有任何反应,它们保持在相同的位置。
是否必须将每个点都放在单独的 TransformGroup 中(由 shape3D 和大小为 1 的 Point3f 数组组成)才能实现?我稍后要使用 100000 个点,如果它们都在单独的 TransformGroups 中,对性能是否不利?有更简单的方法吗?像 shape3D.repaint() 这样的东西,它会根据 plaPTS 中的新值自动更新点的位置。
不要不要使用10000个TransformGroup
实例,这将导致可怕的性能(与单个PointArray
相比)。
你应该看看GeometryArray
JavaDocs,特别是关于通过复制使用数据和通过引用使用数据之间的区别.
较新版本的Java3D只支持复制方法。 (您的方法可以使用 by reference 方法,但您仍然需要触发更新)。
通过复制使用数据的事实意味着当您创建Point3f
数组的复制将它传递给 PointArray
方法的构造函数。所以修改这些点不会影响PointArray
.
相反,您可以使用setCoordinate
方法修改点数。这是一个示例,您可以简单地添加此方法并将 PointArray
传递给它:
private static void moveOnePointOf(final PointArray pa)
{
pa.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
Thread t = new Thread(new Runnable()
{
Point3f p = new Point3f();
@Override
public void run()
{
while (true)
{
pa.getCoordinate(0, p);
p.x = (float)Math.sin(System.currentTimeMillis()/1000.0);;
pa.setCoordinate(0, p);
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
});
t.setDaemon(true);
t.start();
}
进一步的说明和提示:
- 不要不对每个点使用一个线程。这只是一个例子 ;-)
别忘了设置写入坐标的能力:
pointArray.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
您甚至可以考虑完全不使用 Point3f
数组,而是直接在 PointArray
中设置坐标
在某些系统上,本机渲染组件有些奇怪。对于 Java3D 或其他基于 OpenGL 的 windows,这意味着 window 最初是灰色的,除非您调整它的大小或重新绘制它。您可以通过添加
来避免这种情况
System.setProperty("sun.awt.noerasebackground", "true");
作为您的 main
方法的第一行。
我有以下代码在 canvas3D 中绘制 4 个点 window
public final class energon extends JPanel {
int s = 0, count = 0;
public energon() {
setLayout(new BorderLayout());
GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
Canvas3D canvas3D = new Canvas3D(gc);//See the added gc? this is a preferred config
add("Center", canvas3D);
BranchGroup scene = createSceneGraph();
scene.compile();
// SimpleUniverse is a Convenience Utility class
SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
// This moves the ViewPlatform back a bit so the
// objects in the scene can be viewed.
simpleU.getViewingPlatform().setNominalViewingTransform();
simpleU.addBranchGraph(scene);
}
public BranchGroup createSceneGraph() {
BranchGroup lineGroup = new BranchGroup();
Appearance app = new Appearance();
ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f, 204.0f), ColoringAttributes.SHADE_FLAT);
app.setColoringAttributes(ca);
Point3f[] plaPts = new Point3f[4];
for (int i = 0; i < 2; i++) {
for (int j = 0; j <2; j++) {
plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
//Look up line, i and j are divided by 10.0f to be able to
//see the points inside the view screen
count++;
}
}
PointArray pla = new PointArray(4, GeometryArray.COORDINATES);
pla.setCoordinates(0, plaPts);
Shape3D plShape = new Shape3D(pla, app);
TransformGroup objRotate = new TransformGroup();
objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objRotate.addChild(plShape);
lineGroup.addChild(objRotate);
return lineGroup;
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.add(new JScrollPane(new energon()));
frame.setSize(300, 300);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
现在我想添加一个定时任务,定期更新 plaPts Point3f 数组中的一个点的位置。然而,当我调用 plaPts[1].setX(2) 时,屏幕上没有任何反应,它们保持在相同的位置。
是否必须将每个点都放在单独的 TransformGroup 中(由 shape3D 和大小为 1 的 Point3f 数组组成)才能实现?我稍后要使用 100000 个点,如果它们都在单独的 TransformGroups 中,对性能是否不利?有更简单的方法吗?像 shape3D.repaint() 这样的东西,它会根据 plaPTS 中的新值自动更新点的位置。
不要不要使用10000个TransformGroup
实例,这将导致可怕的性能(与单个PointArray
相比)。
你应该看看GeometryArray
JavaDocs,特别是关于通过复制使用数据和通过引用使用数据之间的区别.
较新版本的Java3D只支持复制方法。 (您的方法可以使用 by reference 方法,但您仍然需要触发更新)。
通过复制使用数据的事实意味着当您创建Point3f
数组的复制将它传递给 PointArray
方法的构造函数。所以修改这些点不会影响PointArray
.
相反,您可以使用setCoordinate
方法修改点数。这是一个示例,您可以简单地添加此方法并将 PointArray
传递给它:
private static void moveOnePointOf(final PointArray pa)
{
pa.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
Thread t = new Thread(new Runnable()
{
Point3f p = new Point3f();
@Override
public void run()
{
while (true)
{
pa.getCoordinate(0, p);
p.x = (float)Math.sin(System.currentTimeMillis()/1000.0);;
pa.setCoordinate(0, p);
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
}
}
});
t.setDaemon(true);
t.start();
}
进一步的说明和提示:
- 不要不对每个点使用一个线程。这只是一个例子 ;-)
别忘了设置写入坐标的能力:
pointArray.setCapability(PointArray.ALLOW_COORDINATE_WRITE);
您甚至可以考虑完全不使用
Point3f
数组,而是直接在PointArray
中设置坐标在某些系统上,本机渲染组件有些奇怪。对于 Java3D 或其他基于 OpenGL 的 windows,这意味着 window 最初是灰色的,除非您调整它的大小或重新绘制它。您可以通过添加
来避免这种情况System.setProperty("sun.awt.noerasebackground", "true");
作为您的
main
方法的第一行。