我正在使用名为“Walrus”的Java 3D应用程序,用于显示有向图。该代码已经具有突出显示节点的功能,并在给定其屏幕坐标的情况下在图形中绘制相邻标签。
旋转屏幕后,节点不再突出显示。
我所拥有的是3D中的节点坐标。我需要为它画标签。
使用3D坐标突出显示的代码
Point3d p = new Point3d();
m_graph.getNodeCoordinates(node, p);
PointArray array = new PointArray(1, PointArray.COORDINATES);
array.setCoordinate(0, p);
m_parameters.putModelTransform(gc);
gc.setAppearance(m_parameters.getPickAppearance());
如何使用3D坐标绘制Label(光栅图形会引发错误渲染器:创建立即模式Canvas3D图形上下文时出错)
如何将3D坐标转换为2D屏幕并使用现有代码在2D屏幕点绘制标签
谢谢,
Dakshina
答案 0 :(得分:0)
以下是我用来将3D坐标转换为透视2D,x2和y2是2维坐标,xyz是3D坐标。
使用以下公式:
x2 = cos(30)* x - cos(30)* y
y2 = sin(30)* x + sin(30)* y + z
我选择了角度30,因为它很容易用于透视目的,也用于等距网格在2D纸张上绘制3D。由于z轴是垂直的,x和y是左右60度的轴。 Isometric Grid Picture.
我仍然在进行旋转,但是如果不改变轴,只需在3D中协调旋转。 享受。
答案 1 :(得分:0)
我有一种算法/方法,可以使用[x,y,z]
参数将[x,y]
转换为depth
:
x
值为:(int) (x - (z / depth * x))
y
值为:(int) (y - (z / depth * y))
基本上,深度是焦点。消失点将在[0,0,depth]
。
答案 2 :(得分:-1)
我找到了解决方案。 这是在图像2D坐标
处显示Text3D的功能public void drawLabel(GraphicsContext3D gc, double x, double y, int zOffset, String s) {
boolean frontBufferRenderingState = gc.getFrontBufferRendering();
gc.setBufferOverride(true);
gc.setFrontBufferRendering(true);
Point3d eye = getEye();
double labelZ = zOffset * LABEL_Z_OFFSET_SCALE
+ LABEL_Z_SCALE * eye.z + LABEL_Z_OFFSET;
double xOffset = LABEL_X_OFFSET * m_pixelToMeterScale;
double yOffset = LABEL_Y_OFFSET * m_pixelToMeterScale;
Point3d p = new Point3d(x + xOffset, y + yOffset, 0.0);
{
// Project given (x, y) coordinates to the plane z=labelZ.
// Convert from image-plate to eye coordinates.
p.x -= eye.x;
p.y -= eye.y;
double inversePerspectiveScale = 1.0 - labelZ / eye.z;
p.x *= inversePerspectiveScale;
p.y *= inversePerspectiveScale;
// Convert from eye to image-plate coordinates.
p.x += eye.x;
p.y += eye.y;
}
Transform3D scale = new Transform3D();
scale.set(LABEL_SCALE);
Vector3d t = new Vector3d(p.x, p.y, labelZ);
Transform3D translation = new Transform3D();
translation.set(t);
translation.mul(scale);
Transform3D transform = new Transform3D(m_imageToVworld);
transform.mul(translation);
gc.setModelTransform(transform);
//-----------------
int fontSize=(int)(10*m_magnification);
if(fontSize>20)
fontSize=20;
//---------------
// XXX: Courier may not be available on all systems.
Text2D text = new Text2D(s, new Color3f(1.0f, 1.0f, 1.0f),
"Courier", fontSize, Font.BOLD);
gc.draw(text);
gc.flush(true);
// NOTE: Resetting the model transform here is very important.
// For some reason, not doing this causes the immediate
// following frame to render incorrectly (but subsequent
// frames will render correctly). In some ways, this
// makes sense, because most rendering code assumes that
// GraphicsContext3D has been set to some reasonable
// transform.
gc.setModelTransform(m_objectTransform);
gc.setFrontBufferRendering(frontBufferRenderingState);
}
这是获取3D坐标并将其转换为图像2D坐标并使用上述功能进行渲染的功能
private boolean displayOnScreenLabel(int node, String label) {
boolean success = false;
try {
Transform3D transform = m_parameters.getObjectToEyeTransform();
Point3d nodeC = new Point3d();
m_graph.getNodeCoordinates(node, nodeC);
transform.transform(nodeC);
Point3d eye = m_parameters.getEye();
double perspectiveScale = 1.0 / (1.0 - nodeC.z / eye.z);
double centerX = eye.x + nodeC.x * perspectiveScale;
double centerY = eye.y + nodeC.y * perspectiveScale;
GraphicsContext3D gc = m_canvas.getGraphicsContext3D();
m_parameters.drawLabel(gc, centerX, centerY, m_labelZOffsetCounter++, label);
success = true;
} catch (final java.lang.OutOfMemoryError error) {
JOptionPane.showMessageDialog(m_frame, "The 3D Graphics is unable to find enough memory on your system. Kill the application!", "Out Of Memory!", JOptionPane.ERROR_MESSAGE);
} catch (Exception e) {
success = false;
}
return success;
}