所以我正在制作一个简单的3D图形程序。但我有一个与图形没有直接关系的错误。
我有一个可以翻译,旋转等的Triangle类。我还有一个Shape类,可以从这些三角形中创建形状。因此,当我想移动一个形状时,我可以使用一个形状对象来均匀地移动所有形状。
当我尝试移动形状时会发生错误。所发生的是翻译意味着传递给一行中的所有三角形。但其中一些人的翻译翻了一番。
经过大量的调试后,我发现了一些奇怪的结果,因为似乎有些顶点采用了前一次迭代的顶点的转换,但只有部分。 因此翻译翻了一倍。
我会包含截图,但我的代表不够高。
到目前为止,我唯一的解释是要么某些顶点共享数据。或者其中一些顶点的数据在运行时存储并被使用,因为顶点是相似的。
形状类 - >持有三角形物体
三角类 - >拥有3个顶点对象 - >也有显示和方法翻译
顶点类 - >持有双x,双y,双z
值得注意的是,形状形状类中不同三角形的某些顶点具有相同的顶点。但这不应该是一个问题,因为它们被传递到不同的三角形。
Index: 0 // First Triangle
next check: 1.0 // The z value of the first vertex int the next triangle(index 1)
1.0 // z val. before translation
1.010356248053852, dz: 0.009999833334166664 // z val. after translation
1.0 // z val. before translation
1.010356248053852, dz: 0.009999833334166664 // z val. after translation
1.0 // z val. before translation
1.010356248053852, dz: 0.009999833334166664 // z val. after translation
Index: 1 // Second triangle
next check: 1.5 // next check
1.010356248053852 // z val. before translation
1.0207124961077039, dz: 0.009999833334166664 // z val. after translation
最后两行是重要的。第一个应该是1.0,因为指数0表示它将是(下一个检查:1.0)。 然而,当我们到达第二个三角形时,它已经转换了第一个三角形。因此,再次产生效果。
这种情况不会发生在所有人身上。
感谢您提前向文章提供任何帮助或指示。
public Triangle(Point x, Point y, Point z, byte r, byte g, byte b, double fov)
{
points = new Point[]{x, y, z};
m_r = r;
m_g = g;
m_b = b;
FOV = fov;
}
public void move(double x, double y, double z, double delta)
{
for (int i = 0; i < 3; i++)
{
points[i].setDX(points[i].getDX() + (x * delta));
points[i].setDY(points[i].getDY() + (y * delta));
points[i].setDZ(points[i].getDZ() + (z * delta));
}
}
/ \重要三角代码
public void move(double x, double y, double z, double delta)
{
for (int i = 0; i < index.length; i++)
{
rs.triMove(index[i], x, y, z, delta);
}
}
/ \形状移动代码 rs是所有三角形的集合空间,但是在添加之前错误已经开始。索引是三角形在rs中保存在数组中的位置。
public void triMove(int index, double x, double y, double z, double delta)
{
triangles.get(index).move(x, y, z, delta);
}
/ \ RS类移动代码。
有些可能有用的照片。 目前很好/ \仍然<\ p>
/ \现在有点坏了。其中两个有两倍的z值,另外两个很好。
但他们仍然是同样的错误和相同数量的破碎?
但是有些东西非常如果使用四个三角形进行相同的rec,则会很奇怪。 但显然这是一种修复它的黑客方式,它不会使用更复杂的形状。
答案 0 :(得分:5)
由于你发布了如此少的代码,很难知道实际问题是什么,所以在黑暗中有点关注,但这对我来说非常突出:
值得注意的是,形状形状类中不同三角形的某些顶点具有相同的顶点。但这不应该是一个问题,因为它们被传递到不同的三角形。
我会让每个Triangle
复制每个输入Point
,以确保它们不会干扰其他Triangle
点。
即:
public Triangle(Point x, Point y, Point z, byte r, byte g, byte b, double fov)
{
// This is just an example since I have no idea what your
// Point class actually looks like
points = new Point[]{
new Point(x.getX(), x.getY(), x.getZ()),
new Point(y.getX(), y.getY(), y.getZ()),
new Point(z.getX(), z.getY(), z.getZ()),
};
m_r = r;
m_g = g;
m_b = b;
FOV = fov;
}
<强>更新强>
为了解释发生的事情,这里有一个简短的例子:
Point.java :
public class Point {
int x;
int y;
public Point(final int x, final int y) {
this.x = x;
this.y = y;
System.out.printf("Created point %s at (%s,%s)%n", this, x, y);
}
void move(int dx, int dy) {
x += dx;
y += dy;
System.out.printf("Moved point %s (%s,%s) from (%s,%s) to (%s,%s)%n", this, dx, dy, x - dx, y - dy, x, y);
}
}
Triangle.java :
public class Triangle {
Point a;
Point b;
Point c;
public Triangle(final Point a, final Point b, final Point c) {
this.a = a;
this.b = b;
this.c = c;
System.out.printf("Created triangle %s with points (%s, %s, %s)%n", this, this.a, this.b, this.c);
}
void move(int dx, int dy) {
System.out.printf("Moving triangle %s (%s,%s)%n", this, dx, dy);
a.move(dx, dy);
b.move(dx, dy);
c.move(dx, dy);
}
}
Demo.java :
public class Demo {
public static void main(String[] args) {
Point p1 = new Point(0, 0);
Point p2 = new Point(1, 0);
Point p3 = new Point(0, 1);
Point p4 = new Point(1, 1);
Triangle t1 = new Triangle(p1, p2, p3);
Triangle t2 = new Triangle(p2, p3, p4);
t1.move(1, 1);
t2.move(1, 1);
}
}
运行时,会产生以下输出:
Created point Point@448139f0 at (0,0)
Created point Point@7cca494b at (1,0)
Created point Point@7ba4f24f at (0,1)
Created point Point@3b9a45b3 at (1,1)
Created triangle Triangle@7699a589 with points (Point@448139f0, Point@7cca494b, Point@7ba4f24f)
Created triangle Triangle@58372a00 with points (Point@7cca494b, Point@7ba4f24f, Point@3b9a45b3)
Moving triangle Triangle@7699a589 (1,1)
Moved point Point@448139f0 (1,1) from (0,0) to (1,1)
Moved point Point@7cca494b (1,1) from (1,0) to (2,1)
Moved point Point@7ba4f24f (1,1) from (0,1) to (1,2)
Moving triangle Triangle@58372a00 (1,1)
Moved point Point@7cca494b (1,1) from (2,1) to (3,2)
Moved point Point@7ba4f24f (1,1) from (1,2) to (2,3)
Moved point Point@3b9a45b3 (1,1) from (1,1) to (2,2)
如您所见,因为两个三角形共享一些点对象,所以这些点会移动两次。
如果我们将Triangle
中的构造函数更改为这样:
public Triangle(final Point a, final Point b, final Point c) {
this.a = new Point(a.x, a.y);
this.b = new Point(b.x, b.y);
this.c = new Point(c.x, c.y);
System.out.printf("Created triangle %s with points (%s, %s, %s)%n", this, this.a, this.b, this.c);
}
我们改为获得以下输出:
Created point Point@448139f0 at (0,0)
Created point Point@7cca494b at (1,0)
Created point Point@7ba4f24f at (0,1)
Created point Point@3b9a45b3 at (1,1)
Created point Point@7699a589 at (0,0)
Created point Point@58372a00 at (1,0)
Created point Point@4dd8dc3 at (0,1)
Created triangle Triangle@6d03e736 with points (Point@7699a589, Point@58372a00, Point@4dd8dc3)
Created point Point@568db2f2 at (1,0)
Created point Point@378bf509 at (0,1)
Created point Point@5fd0d5ae at (1,1)
Created triangle Triangle@2d98a335 with points (Point@568db2f2, Point@378bf509, Point@5fd0d5ae)
Moving triangle Triangle@6d03e736 (1,1)
Moved point Point@7699a589 (1,1) from (0,0) to (1,1)
Moved point Point@58372a00 (1,1) from (1,0) to (2,1)
Moved point Point@4dd8dc3 (1,1) from (0,1) to (1,2)
Moving triangle Triangle@2d98a335 (1,1)
Moved point Point@568db2f2 (1,1) from (1,0) to (2,1)
Moved point Point@378bf509 (1,1) from (0,1) to (1,2)
Moved point Point@5fd0d5ae (1,1) from (1,1) to (2,2)
这可以正常工作,因为两个三角形不再共享任何点对象。
避免这种陷阱的一个好方法是始终复制构造函数参数(defensive copying)或使用immutable objects。