3d 中的点 space 无故接近 3d 中的平面 space
Point in 3d space approaching Planes in 3d space without reason
Java,程序,我有一个 Point3d class w/ x,y,z 坐标,以及以下平均函数:
public static Point3d average(Point3d a, Point3d b){
a.add(b);
a.x/=2;
a.y/=2;
a.z/=2;
return a;
}
我也有这个 class 用于 3d 中的 2dPlane space 由 3 个 3d 点之间的三角形组成:
package com.funguscow.model;
import com.funguscow.obj.Point3d;
import com.funguscow.obj.Vector3d;
public class TriPlane {
public Point3d a, b, c;
private Vector3d normal;
private float d;
public TriPlane(Point3d x, Point3d y, Point3d z){
a = x;
b = y;
c = z;
Vector3d ab = Vector3d.Vector3dPMinus(a, b);
//System.out.println(ab.x + ", " + ab.y + ", " + ab.z);
normal = Vector3d.crossProduct(
Vector3d.Vector3dPMinus(a, b),
Vector3d.Vector3dPMinus(a, c));
d = Vector3d.dotProduct(normal, Vector3d.VectorFromPoint3d(a));
}
public Vector3d getNormal(){
return normal;
}
public float getRelativeOnPlane(Point3d test){
//System.out.println(normal.x + ", " + normal.y + ", " + normal.z);
return Vector3d.dotProduct(normal, Vector3d.VectorFromPoint3d(test)) - d;
}
}
getRelativeOnPlane 是找出特定点在平面的哪一侧。它看起来对你有用吗?你能看到它有什么问题吗?
无论如何,这是个大问题,我有以下 class 的 CubeCollider,扩展了抽象的 class Collider,它设置了六个 TriPlanes 来检查一个点是否在立方体内或不是:
package com.funguscow.model;
import com.funguscow.obj.Point3d;
import com.funguscow.obj.Vector3d;
public class CubeCollider extends Collider{
public Point3d a, b, c, d, e, f, g, h;
public CubeCollider(){
a = new Point3d(0, 0, 0);
b = new Point3d(0, 0, 0);
c = new Point3d(0, 0, 0);
d = new Point3d(0, 0, 0);
e = new Point3d(0, 0, 0);
f = new Point3d(0, 0, 0);
g = new Point3d(0, 0, 0);
h = new Point3d(0, 0, 0);
}
public CubeCollider setCube(Cube cube){
return setCube((float)cube.lines.get(0).start.x,
(float)cube.lines.get(0).start.y, (float)cube.lines.get(0).start.z,
(float)cube.lines.get(11).end.x, (float)cube.lines.get(11).end.y, (float)cube.lines.get(11).end.z);
}
public CubeCollider setCube(float x, float y, float z, float m, float n, float o){
//System.out.println(x + ", " + y + ", " + z + ", " + m + ", " + n + ", " + o);
a.x = b.x = c.x = d.x = x;
e.x = f.x = g.x = h.x = m;
a.y = c.y = e.y = g.y = y;
b.y = d.y = f.y = h.y = n;
a.z = b.z = e.z = f.z = z;
c.z = d.z = g.z = h.z = o;
return this;
}
public boolean shouldBother(Point3d p){
Point3d center = Point3d.average(a, h);
float dist = Vector3d.Vector3dPMinus(p, center).getMagnitude();
if(dist > Vector3d.Vector3dPMinus(center, a).getMagnitude())return false;
if(dist > Vector3d.Vector3dPMinus(center, d).getMagnitude())return false;
if(dist > Vector3d.Vector3dPMinus(center, g).getMagnitude())return false;
return true;
}
public boolean isInBounds(Point3d p){
//System.out.println((a.x - b.x) + ", " + (a.y - b.y) + ", " + (a.z - b.z));
TriPlane[] collider = new TriPlane[]{new TriPlane(a, b, c),
new TriPlane(a, b, e),
new TriPlane(e, f, g),
new TriPlane(c, d, g),
new TriPlane(a, c, e),
new TriPlane(b, d, f)};
Point3d center = Point3d.average(a, h);
for(TriPlane plane : collider){
float should = plane.getRelativeOnPlane(center);
int sign = (should < 0) ? -1 : (should == 0) ? 0 : 1;
float real = plane.getRelativeOnPlane(p);
int rSign = (real < 0) ? -1 : (real == 0) ? 0 : 1;
System.out.println("Center: " + center.x + ", " + center.y + ", " + center.z);
System.out.println("Bound check: " + should + ", " + real);
if(sign != rSign && real != 0 && should != 0)return false;
}
return true;
}
}
函数isInBounds中的点'center'使用了点a和h的平均值,但是有一些问题。来自 isInBounds 函数的 "Bound check: " 之类的调试报告 'should'(平面法向量和点中心的点积)接近零,直到经过几次(十几个)迭代检查,它正好变成 0.0。有人可以告诉我为什么会这样吗?
如果我没记错的话,函数 getRelativePointOnPlane 返回零应该意味着该点在 on 平面上,但是它正在测试(中心)的点,如果我没记错的话,应该是在所有平面之间,而不是在任何平面之间。是我使用这些函数的逻辑错了,还是我写函数的代码写错了?
这是控制台读取的内容:
Center: 100.0, 100.0, 40.0
Bound check: -4000000.0, -1.2E7
Center: 100.0, 100.0, 40.0
Bound check: 4000000.0, 4800000.0
Center: 100.0, 100.0, 40.0
Bound check: 4000000.0, -4000000.0
Center: 50.0, 50.0, -10.0
Bound check: -2000000.0, -1000000.0
Center: 50.0, 50.0, -10.0
Bound check: 2000000.0, 5000000.0
Center: 50.0, 50.0, -10.0
Bound check: 2000000.0, -4000000.0
Center: 25.0, 25.0, -35.0
Bound check: -1000000.0, 5100000.0
Center: 12.5, 12.5, -47.5
Bound check: -500000.0, 8650000.0
Center: 6.25, 6.25, -53.75
Bound check: -250000.0, 1.0875E7
Center: 3.125, 3.125, -56.875
Bound check: -125000.0, 1.24125E7
Center: 1.5625, 1.5625, -58.4375
Bound check: -62500.0, 1.359375E7
Center: 0.78125, 0.78125, -59.21875
Bound check: -31250.0, 1.4590625E7
Center: 0.390625, 0.390625, -59.609375
Bound check: -15625.0, 1.5492187E7
Center: 0.1953125, 0.1953125, -59.8046875
Bound check: -7812.5, 1.6344532E7
Center: 0.09765625, 0.09765625, -59.90234375
Bound check: -3906.25, 1.7171484E7
Center: 0.048828125, 0.048828125, -59.951171875
Bound check: -1953.0, 1.7985352E7
Center: 0.0244140625, 0.0244140625, -59.9755859375
Bound check: -976.5, 1.879248E7
Center: 0.01220703125, 0.01220703125, -59.98779296875
Bound check: -488.25, 1.9596142E7
Center: 0.006103515625, 0.006103515625, -59.993896484375
Bound check: -244.25, 2.0398024E7
Center: 0.0030517578125, 0.0030517578125, -59.9969482421875
Bound check: -122.25, 2.1198986E7
Center: 0.00152587890625, 0.00152587890625, -59.99847412109375
Bound check: -61.0, 2.1999482E7
Center: 7.62939453125E-4, 7.62939453125E-4, -59.999237060546875
Bound check: -30.5, 2.2799734E7
Center: 3.814697265625E-4, 3.814697265625E-4, -59.99961853027344
Bound check: -15.25, 2.3599864E7
Center: 1.9073486328125E-4, 1.9073486328125E-4, -59.99980926513672
Bound check: -7.5, 2.439993E7
Center: 9.5367431640625E-5, 9.5367431640625E-5, -59.99990463256836
Bound check: -4.0, 2.5199964E7
Center: 4.76837158203125E-5, 4.76837158203125E-5, -59.99995231628418
Bound check: -2.0, 2.599998E7
Center: 2.384185791015625E-5, 2.384185791015625E-5, -59.99997615814209
Bound check: -1.0, 2.6799992E7
Center: 1.1920928955078125E-5, 1.1920928955078125E-5, -59.999988079071045
Bound check: -0.5, 2.7599994E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.0, 2.8399998E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.25, 2.4399998E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.23841858, -4000000.0
Center: 2.9802322387695312E-6, 2.9802322387695312E-6, -59.99999701976776
Bound check: 0.0, 2.92E7
您的 average
方法更改了 a
的值,使其与平均点相同。所以你的立方体不是立方体,在你调用 average
之后 - 其中三个面已经旋转到新的位置。因此 collider
循环中发生的任何事情都是错误的。
Java,程序,我有一个 Point3d class w/ x,y,z 坐标,以及以下平均函数:
public static Point3d average(Point3d a, Point3d b){
a.add(b);
a.x/=2;
a.y/=2;
a.z/=2;
return a;
}
我也有这个 class 用于 3d 中的 2dPlane space 由 3 个 3d 点之间的三角形组成:
package com.funguscow.model;
import com.funguscow.obj.Point3d;
import com.funguscow.obj.Vector3d;
public class TriPlane {
public Point3d a, b, c;
private Vector3d normal;
private float d;
public TriPlane(Point3d x, Point3d y, Point3d z){
a = x;
b = y;
c = z;
Vector3d ab = Vector3d.Vector3dPMinus(a, b);
//System.out.println(ab.x + ", " + ab.y + ", " + ab.z);
normal = Vector3d.crossProduct(
Vector3d.Vector3dPMinus(a, b),
Vector3d.Vector3dPMinus(a, c));
d = Vector3d.dotProduct(normal, Vector3d.VectorFromPoint3d(a));
}
public Vector3d getNormal(){
return normal;
}
public float getRelativeOnPlane(Point3d test){
//System.out.println(normal.x + ", " + normal.y + ", " + normal.z);
return Vector3d.dotProduct(normal, Vector3d.VectorFromPoint3d(test)) - d;
}
}
getRelativeOnPlane 是找出特定点在平面的哪一侧。它看起来对你有用吗?你能看到它有什么问题吗?
无论如何,这是个大问题,我有以下 class 的 CubeCollider,扩展了抽象的 class Collider,它设置了六个 TriPlanes 来检查一个点是否在立方体内或不是:
package com.funguscow.model;
import com.funguscow.obj.Point3d;
import com.funguscow.obj.Vector3d;
public class CubeCollider extends Collider{
public Point3d a, b, c, d, e, f, g, h;
public CubeCollider(){
a = new Point3d(0, 0, 0);
b = new Point3d(0, 0, 0);
c = new Point3d(0, 0, 0);
d = new Point3d(0, 0, 0);
e = new Point3d(0, 0, 0);
f = new Point3d(0, 0, 0);
g = new Point3d(0, 0, 0);
h = new Point3d(0, 0, 0);
}
public CubeCollider setCube(Cube cube){
return setCube((float)cube.lines.get(0).start.x,
(float)cube.lines.get(0).start.y, (float)cube.lines.get(0).start.z,
(float)cube.lines.get(11).end.x, (float)cube.lines.get(11).end.y, (float)cube.lines.get(11).end.z);
}
public CubeCollider setCube(float x, float y, float z, float m, float n, float o){
//System.out.println(x + ", " + y + ", " + z + ", " + m + ", " + n + ", " + o);
a.x = b.x = c.x = d.x = x;
e.x = f.x = g.x = h.x = m;
a.y = c.y = e.y = g.y = y;
b.y = d.y = f.y = h.y = n;
a.z = b.z = e.z = f.z = z;
c.z = d.z = g.z = h.z = o;
return this;
}
public boolean shouldBother(Point3d p){
Point3d center = Point3d.average(a, h);
float dist = Vector3d.Vector3dPMinus(p, center).getMagnitude();
if(dist > Vector3d.Vector3dPMinus(center, a).getMagnitude())return false;
if(dist > Vector3d.Vector3dPMinus(center, d).getMagnitude())return false;
if(dist > Vector3d.Vector3dPMinus(center, g).getMagnitude())return false;
return true;
}
public boolean isInBounds(Point3d p){
//System.out.println((a.x - b.x) + ", " + (a.y - b.y) + ", " + (a.z - b.z));
TriPlane[] collider = new TriPlane[]{new TriPlane(a, b, c),
new TriPlane(a, b, e),
new TriPlane(e, f, g),
new TriPlane(c, d, g),
new TriPlane(a, c, e),
new TriPlane(b, d, f)};
Point3d center = Point3d.average(a, h);
for(TriPlane plane : collider){
float should = plane.getRelativeOnPlane(center);
int sign = (should < 0) ? -1 : (should == 0) ? 0 : 1;
float real = plane.getRelativeOnPlane(p);
int rSign = (real < 0) ? -1 : (real == 0) ? 0 : 1;
System.out.println("Center: " + center.x + ", " + center.y + ", " + center.z);
System.out.println("Bound check: " + should + ", " + real);
if(sign != rSign && real != 0 && should != 0)return false;
}
return true;
}
}
函数isInBounds中的点'center'使用了点a和h的平均值,但是有一些问题。来自 isInBounds 函数的 "Bound check: " 之类的调试报告 'should'(平面法向量和点中心的点积)接近零,直到经过几次(十几个)迭代检查,它正好变成 0.0。有人可以告诉我为什么会这样吗? 如果我没记错的话,函数 getRelativePointOnPlane 返回零应该意味着该点在 on 平面上,但是它正在测试(中心)的点,如果我没记错的话,应该是在所有平面之间,而不是在任何平面之间。是我使用这些函数的逻辑错了,还是我写函数的代码写错了?
这是控制台读取的内容:
Center: 100.0, 100.0, 40.0
Bound check: -4000000.0, -1.2E7
Center: 100.0, 100.0, 40.0
Bound check: 4000000.0, 4800000.0
Center: 100.0, 100.0, 40.0
Bound check: 4000000.0, -4000000.0
Center: 50.0, 50.0, -10.0
Bound check: -2000000.0, -1000000.0
Center: 50.0, 50.0, -10.0
Bound check: 2000000.0, 5000000.0
Center: 50.0, 50.0, -10.0
Bound check: 2000000.0, -4000000.0
Center: 25.0, 25.0, -35.0
Bound check: -1000000.0, 5100000.0
Center: 12.5, 12.5, -47.5
Bound check: -500000.0, 8650000.0
Center: 6.25, 6.25, -53.75
Bound check: -250000.0, 1.0875E7
Center: 3.125, 3.125, -56.875
Bound check: -125000.0, 1.24125E7
Center: 1.5625, 1.5625, -58.4375
Bound check: -62500.0, 1.359375E7
Center: 0.78125, 0.78125, -59.21875
Bound check: -31250.0, 1.4590625E7
Center: 0.390625, 0.390625, -59.609375
Bound check: -15625.0, 1.5492187E7
Center: 0.1953125, 0.1953125, -59.8046875
Bound check: -7812.5, 1.6344532E7
Center: 0.09765625, 0.09765625, -59.90234375
Bound check: -3906.25, 1.7171484E7
Center: 0.048828125, 0.048828125, -59.951171875
Bound check: -1953.0, 1.7985352E7
Center: 0.0244140625, 0.0244140625, -59.9755859375
Bound check: -976.5, 1.879248E7
Center: 0.01220703125, 0.01220703125, -59.98779296875
Bound check: -488.25, 1.9596142E7
Center: 0.006103515625, 0.006103515625, -59.993896484375
Bound check: -244.25, 2.0398024E7
Center: 0.0030517578125, 0.0030517578125, -59.9969482421875
Bound check: -122.25, 2.1198986E7
Center: 0.00152587890625, 0.00152587890625, -59.99847412109375
Bound check: -61.0, 2.1999482E7
Center: 7.62939453125E-4, 7.62939453125E-4, -59.999237060546875
Bound check: -30.5, 2.2799734E7
Center: 3.814697265625E-4, 3.814697265625E-4, -59.99961853027344
Bound check: -15.25, 2.3599864E7
Center: 1.9073486328125E-4, 1.9073486328125E-4, -59.99980926513672
Bound check: -7.5, 2.439993E7
Center: 9.5367431640625E-5, 9.5367431640625E-5, -59.99990463256836
Bound check: -4.0, 2.5199964E7
Center: 4.76837158203125E-5, 4.76837158203125E-5, -59.99995231628418
Bound check: -2.0, 2.599998E7
Center: 2.384185791015625E-5, 2.384185791015625E-5, -59.99997615814209
Bound check: -1.0, 2.6799992E7
Center: 1.1920928955078125E-5, 1.1920928955078125E-5, -59.999988079071045
Bound check: -0.5, 2.7599994E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.0, 2.8399998E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.25, 2.4399998E7
Center: 5.9604644775390625E-6, 5.9604644775390625E-6, -59.99999403953552
Bound check: 0.23841858, -4000000.0
Center: 2.9802322387695312E-6, 2.9802322387695312E-6, -59.99999701976776
Bound check: 0.0, 2.92E7
您的 average
方法更改了 a
的值,使其与平均点相同。所以你的立方体不是立方体,在你调用 average
之后 - 其中三个面已经旋转到新的位置。因此 collider
循环中发生的任何事情都是错误的。