2011-12-29 140 views
1

由于某些原因,当我尝试通过检查点的半径来制作Java中的球体时,它给了我一个立方体而不是球体。我的代码或我的公式存在问题吗?Java中的球体绘图

for(double X = 0; X < diameter; X++) 
     { 
      //mcspace.logger.info("X = " + Double.toString(X)); 
      for(double Y = 0; Y < diameter; Y++) 
      { 
       //mcspace.logger.info("Y = " + Double.toString(Y)); 
       for(double Z = 0; Z < diameter; Z++) 
       { 
        //mcspace.logger.info("Z = " + Double.toString(Z)); 
        int radius = diameter/2; 

        double cX = X; 
        double cZ = Z; 
        double cY = Y; 

        if (X > radius){cX -= radius;} 
        if (Y > radius){cY -= radius;} 
        if (Z > radius){cZ -= radius;} 

        double Cr = Math.sqrt(Math.sqrt(Math.pow(cX,2) + Math.pow(cY,2)) + Math.pow(cZ,2)); 

        if(Cr <= radius) 
        { 
         SetInShere(X,Y,Z); 
         // This is just a function that is in my code but the problem is that almost all the points are in the sphere, I almost always get a cube instead of a sphere... 
        } 
       } 
     } 
} 
+0

我不我不明白这个问题。什么是“一个点的半径”?另外,尝试提供一个实际编译和运行的最小示例。没有这些,很难理解你的代码应该做什么。 – sleske 2011-12-29 18:37:14

+0

移动int radius =直径/ 2;出于效率的原因,在你的循环之外。 And do double Cr = Math.hypot(Math.hypot(cX,cY),cZ); 这个更简单,更不容易出错,并且(除非我的数学学位是完全浪费时间)应该可以工作。 编辑:@BRPocock的想法更好 – 2012-01-03 00:12:54

回答

2

假设你的球体的原点是(0,0,0),我认为你在那里有一个额外的平方根。

此外,乘以X * X比Math.pow(X,2)快好几倍......

我还要移动半径计算的循环之外,并使其成为double休息一下就好了,以防万一的舍入误差会来咬你。

(你可以用X += foo更换X++增量,以与更小或更大的步骤这个版本的工作,以及。)

 double radius = diameter/2; 

    for(double X = -radius; X < radius; X++) 
     for(double Y = -radius; Y < radius; Y++) 
      for(double Z = -radius; Z < radius; Z++) 
       if(Math.sqrt((X * X) + (Y * Y) + (Z * Z)) <= radius) 
        SetInShere(X,Y,Z); 
0

更优的解决方案将是:

int r2=radius*radius; 
for(int X = -radius; X <= radius; X++){ 
    int x2=X*X; 
    for(int Y = -radius; Y <= radius; Y++){ 
     int y2=Y*Y; 
     for(int Z = -radius; Z <= radius; Z++) 
      if(x2 + y2 + (Z * Z) <= r2) 
       SetInShere(X,Y,Z); 
    } 
}