编辑:DASHED LINE之后的新代码和输出
这是一个学校作业,但我找不到任何可以解决这个问题的东西。程序假设要做的是获取一个GeneralPath对象,并使用一个名为RotatedShape的类创建一个Shape3D对象。它有一个构造函数(项目所需的唯一构造函数),它将GeneralPath作为参数。这样,路径意味着围绕轴旋转以显示实心形状,类似于圆环。代码基于我正在使用的教科书中的代码,因为班级中的大多数项目通常都是。
此处发生异常:qa.setCoordinates(i * m,ptsList);它位于RotatedShape类中,靠近底部。我知道问题来自于使用ptsList作为参数,因为早期我在初始化时遇到与Point3d数组相同的问题,因此它的大小当前设置为100作为占位符。
运行时,GUI不显示任何内容,我在控制台输出窗口中显示:
x = 0.1 y = -0.5
Exception in thread "Thread-2" java.lang.NullPointerException
at javax.media.j3d.GeometryArrayRetained.setCoordinates(GeometryArrayRetained.java:3849)
at javax.media.j3d.GeometryArrayRetained.setCoordinates(GeometryArrayRetained.java:3849)
at javax.media.j3d.GeometryArray.setCoordinates(GeometryArray.java:1469)
at RotatedShape.<init>(Project8.java:202)
at Project8.createSceneGraph(Project8.java:58)
at Project8.init(Project8.java:27)
at com.sun.j3d.utils.applet.MainFrame.run(MainFrame.java:267)
at java.lang.Thread.run(Thread.java:724)
BUILD SUCCESSFUL (total time: 8 seconds)
我可以清楚地看到错误发生的位置,我知道问题是什么,但我不知道如何解决它。关于初始化数组或其他什么可能是愚蠢的,但我似乎找不到任何有用的东西。
下面是教授想要的所有文件中的代码。
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.util.Vector;
public class Project8 extends Applet {
public static void main(String[] args) {
new MainFrame(new Project8(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc
= SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
Transform3D tr = new Transform3D();
tr.setScale(0.8);
tr.setRotation(new AxisAngle4d(1, 0, 0, Math.PI / 6));
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
GeneralPath path = new GeneralPath();
path.moveTo(0.1f, -0.5f);
path.quadTo(0.5f, 1, 0.8f, 0.5f);
path.lineTo(1, 0.2f);
path.closePath();
Shape3D shape = new RotatedShape(path);
Appearance ap = new Appearance();
ap.setMaterial(new Material());
shape.setAppearance(ap);
tg.addChild(shape);
Alpha alpha = new Alpha(-1, 8000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
// background and lights
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.blue));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white),
new Point3f(3f, 3f, 3f), new Point3f(1f, 0f, 0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
}
class RotatedShape extends Shape3D {
public RotatedShape(GeneralPath path) {
int depth = 100;
PathIterator iter = path.getPathIterator(new AffineTransform());
Point3d[] ptsList = new Point3d[depth];
float[] seg = new float[6];
float x = 0, y = 0;
float x0 = 0, y0 = 0;
int pos = 0;
while (!iter.isDone()) {
int segType = iter.currentSegment(seg);
switch (segType) {
case PathIterator.SEG_MOVETO:
x = x0 = seg[0];
y = y0 = seg[1];
System.out.println("x = " + x + " y = " + y);
ptsList[pos] = new Point3d(x, y, 0);
pos++;
break;
case PathIterator.SEG_LINETO:
x = seg[0];
y = seg[1];
ptsList[pos] = new Point3d(x, y, 0);
pos++;
break;
case PathIterator.SEG_QUADTO:
for (int i = 1; i < 10; i++) {
float t = (float) i / 10f;
float xi = (1 - t) * (1 - t) * x + 2 * t * (1 - t) * seg[0] + t * t * seg[2];
float yi = (1 - t) * (1 - t) * y + 2 * t * (1 - t) * seg[1] + t * t * seg[3];
ptsList[pos] = new Point3d(xi, yi, 0);
pos++;
}
x = seg[2];
y = seg[3];
ptsList[pos] = new Point3d(x, y, 0);
pos++;
break;
case PathIterator.SEG_CUBICTO:
for (int i = 1; i < 20; i++) {
float t = (float) i / 20f;
float xi = (1 - t) * (1 - t) * (1 - t) * x + 3 * t * (1 - t) * (1 - t) * seg[0]
+ 3 * t * t * (1 - t) * seg[2] + t * t * t * seg[4];
float yi = (1 - t) * (1 - t) * (1 - t) * y + 3 * t * (1 - t) * (1 - t) * seg[1]
+ 3 * t * t * (1 - t) * seg[3] + t * t * t * seg[5];
ptsList[pos] = new Point3d(xi, yi, 0);
pos++;
}
x = seg[2];
y = seg[3];
ptsList[pos] = new Point3d(x, y, 0);
pos++;
break;
case PathIterator.SEG_CLOSE:
x = x0;
y = y0;
ptsList[pos] = new Point3d(x, y, 0);
pos++;
break;
}
iter.next();
}
int m = 20;
//int n = 40;
int n = ptsList.length;
Transform3D rot2 = new Transform3D();
rot2.rotY(2.0 * Math.PI / n);
IndexedQuadArray qa = new IndexedQuadArray(m * n,
IndexedQuadArray.COORDINATES, 4 * m * n);
int quadIndex = 0;
for (int i = 0; i < n; i++) {
qa.setCoordinates(i * m, ptsList);
for (int j = 0; j < m; j++) {
rot2.transform(ptsList[j]);
int[] quadCoords = {i * m + j, ((i + 1) % n) * m + j,
((i + 1) % n) * m + ((j + 1) % m), i * m + ((j + 1) % m)};
qa.setCoordinateIndices(quadIndex, quadCoords);
quadIndex += 4;
}
}
GeometryInfo gi = new GeometryInfo(qa);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
this.setGeometry(gi.getGeometryArray());
}
}
import javax.vecmath.*;
import java.awt.*;
import java.awt.event.*;
import javax.media.j3d.*;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import java.applet.*;
import com.sun.j3d.utils.applet.MainFrame;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.util.Vector;
public class Project8 extends Applet {
public static void main(String[] args) {
new MainFrame(new Project8(), 640, 480);
}
public void init() {
// create canvas
GraphicsConfiguration gc
= SimpleUniverse.getPreferredConfiguration();
Canvas3D cv = new Canvas3D(gc);
setLayout(new BorderLayout());
add(cv, BorderLayout.CENTER);
BranchGroup bg = createSceneGraph();
bg.compile();
SimpleUniverse su = new SimpleUniverse(cv);
su.getViewingPlatform().setNominalViewingTransform();
su.addBranchGraph(bg);
}
private BranchGroup createSceneGraph() {
BranchGroup root = new BranchGroup();
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
root.addChild(spin);
Transform3D tr = new Transform3D();
tr.setScale(0.8);
tr.setRotation(new AxisAngle4d(1, 0, 0, Math.PI / 6));
TransformGroup tg = new TransformGroup(tr);
spin.addChild(tg);
GeneralPath path = new GeneralPath();
path.moveTo(0.1f, -0.5f);
path.quadTo(0.5f, 1, 0.8f, 0.5f);
path.lineTo(1, 0.2f);
path.closePath();
Shape3D shape = new RotatedShape(path);
Appearance ap = new Appearance();
ap.setMaterial(new Material());
shape.setAppearance(ap);
tg.addChild(shape);
Alpha alpha = new Alpha(-1, 8000);
RotationInterpolator rotator = new RotationInterpolator(alpha, spin);
BoundingSphere bounds = new BoundingSphere();
rotator.setSchedulingBounds(bounds);
spin.addChild(rotator);
// background and lights
Background background = new Background(1.0f, 1.0f, 1.0f);
background.setApplicationBounds(bounds);
root.addChild(background);
AmbientLight light = new AmbientLight(true, new Color3f(Color.blue));
light.setInfluencingBounds(bounds);
root.addChild(light);
PointLight ptlight = new PointLight(new Color3f(Color.white),
new Point3f(3f, 3f, 3f), new Point3f(1f, 0f, 0f));
ptlight.setInfluencingBounds(bounds);
root.addChild(ptlight);
return root;
}
}
class RotatedShape extends Shape3D {
public RotatedShape(GeneralPath path) {
int depth = 100;
PathIterator iter = path.getPathIterator(new AffineTransform());
Vector ptsVector = new Vector();
float[] seg = new float[6];
float x = 0, y = 0;
float x0 = 0, y0 = 0;
int pos = 0;
while (!iter.isDone()) {
int segType = iter.currentSegment(seg);
switch (segType) {
case PathIterator.SEG_MOVETO:
x = x0 = seg[0];
y = y0 = seg[1];
ptsVector.add(new Point3d(x, y, 0));
pos++;
break;
case PathIterator.SEG_LINETO:
x = seg[0];
y = seg[1];
ptsVector.add(new Point3d(x, y, 0));
pos++;
break;
case PathIterator.SEG_QUADTO:
for (int i = 1; i < 10; i++) {
float t = (float) i / 10f;
float xi = (1 - t) * (1 - t) * x + 2 * t * (1 - t) * seg[0] + t * t * seg[2];
float yi = (1 - t) * (1 - t) * y + 2 * t * (1 - t) * seg[1] + t * t * seg[3];
ptsVector.add(new Point3d(xi, yi, 0));
pos++;
}
x = seg[2];
y = seg[3];
ptsVector.add(new Point3d(x, y, 0));
pos++;
break;
case PathIterator.SEG_CUBICTO:
for (int i = 1; i < 20; i++) {
float t = (float) i / 20f;
float xi = (1 - t) * (1 - t) * (1 - t) * x + 3 * t * (1 - t) * (1 - t) * seg[0]
+ 3 * t * t * (1 - t) * seg[2] + t * t * t * seg[4];
float yi = (1 - t) * (1 - t) * (1 - t) * y + 3 * t * (1 - t) * (1 - t) * seg[1]
+ 3 * t * t * (1 - t) * seg[3] + t * t * t * seg[5];
ptsVector.add(new Point3d(xi, yi, 0));
pos++;
}
x = seg[2];
y = seg[3];
ptsVector.add(new Point3d(x, y, 0));
pos++;
break;
case PathIterator.SEG_CLOSE:
x = x0;
y = y0;
ptsVector.add(new Point3d(x, y, 0));
pos++;
break;
}
iter.next();
}
for (int i = 0; i < ptsVector.size(); i++)
System.out.println("Vector = " + ptsVector.elementAt(i) + " at " + i);
System.out.println("pos = " + pos);
Point3d[] ptsArray = null;
for (int i = 0; i < ptsVector.size(); i++) {
ptsArray[i] = (Point3d) ptsVector.elementAt(i);
}
// Point3d[] ptsArray = ptsVector.toArray(new Point3d(ptsVector.size()));
int m = 20;
//int n = 40;
int n = ptsArray.length;
Transform3D rot2 = new Transform3D();
rot2.rotY(2.0 * Math.PI / n);
IndexedQuadArray qa = new IndexedQuadArray(m * n,
IndexedQuadArray.COORDINATES, 4 * m * n);
int quadIndex = 0;
for (int i = 0; i < n; i++) {
System.out.println("i = " + i);
qa.setCoordinates(i * m, ptsArray);
for (int j = 0; j < m; j++) {
rot2.transform(ptsArray[j]);
int[] quadCoords = {i * m + j, ((i + 1) % n) * m + j,
((i + 1) % n) * m + ((j + 1) % m), i * m + ((j + 1) % m)};
qa.setCoordinateIndices(quadIndex, quadCoords);
quadIndex += 4;
}
}
GeometryInfo gi = new GeometryInfo(qa);
NormalGenerator ng = new NormalGenerator();
ng.generateNormals(gi);
this.setGeometry(gi.getGeometryArray());
}
}
输出:
run:
Vector = (0.10000000149011612, -0.5, 0.0) at 0
Vector = (0.17899999022483826, -0.2199999839067459, 0.0) at 1
Vector = (0.25600001215934753, 0.020000001415610313, 0.0) at 2
Vector = (0.3310000002384186, 0.2200000286102295, 0.0) at 3
Vector = (0.40400004386901855, 0.3800000250339508, 0.0) at 4
Vector = (0.4750000238418579, 0.5, 0.0) at 5
Exception in thread "Thread-2" java.lang.NullPointerException
Vector = (0.5440000295639038, 0.5800000429153442, 0.0) at 6
at RotatedShape.<init>(Project8.java:197)
Vector = (0.6110000014305115, 0.6200000047683716, 0.0) at 7
Vector = (0.6759999990463257, 0.6200000047683716, 0.0) at 8
Vector = (0.7389999628067017, 0.5800000429153442, 0.0) at 9
Vector = (0.800000011920929, 0.5, 0.0) at 10
Vector = (1.0, 0.20000000298023224, 0.0) at 11
Vector = (0.10000000149011612, -0.5, 0.0) at 12
pos = 13
at Project8.createSceneGraph(Project8.java:58)
at Project8.init(Project8.java:27)
at com.sun.j3d.utils.applet.MainFrame.run(MainFrame.java:267)
at com.sun.j3d.utils.applet.MainFrame.run(MainFrame.java:267)
at java.lang.Thread.run(Thread.java:724)