【问题标题】:Sphere-Sphere intersection and Circle-Sphere intersectionSphere-Sphere 相交和 Circle-Sphere 相交
【发布时间】:2014-05-28 18:00:31
【问题描述】:

我有圆-圆相交的代码。但我需要将其扩展为 3-D。你能帮我写一下函数吗?

static class Point{

    double x, y, z;
    int dimension;
    Point(double x, double y, double z) {
        this.x = x;
        this.y = y;
        this.z = z;
        dimension = 3;
    }

    Point sub(Point p2) {
        return new Point(x - p2.x, y - p2.y, z - p2.z);
    }
    Point add(Point p2) {
        return new Point(x + p2.x, y + p2.y, z + p2.z);
    }
    double distance(Point p2) {
        return Math.sqrt((x - p2.x)*(x - p2.x) + (y - p2.y)*(y - p2.y) + (z - p2.z)*(z - p2.z));
    }
    Point normal() {
        double length = Math.sqrt(x*x + y*y + z*z);
        return new Point(x/length, y/length, z/length);
    }
    Point scale(double s) {
        return new Point(x*s, y*s, z*s);
    }

    double[] array()
    {
        return new double[]{x,y,z};
    }
}

static class Circle {

    double x, y, r, left;
    Circle(double x, double y, double r) {
        this.x = x;
        this.y = y;
        this.r = r;
        left = x - r;
    }
    Circle(double[] c, double r) {
        this(c[0], c[1], r); 
    }
    Circle(Point c, double r)
    {
        this(c.x, c.y, r);
    }
    Point[] intersections(Circle c) 
    {
        Point P0 = new Point(x, y,0);
        Point P1 = new Point(c.x, c.y,0);
        double d, a, h;
        d = P0.distance(P1);
        a = (r*r - c.r*c.r + d*d)/(2*d);
        h = Math.sqrt(r*r - a*a);
        if(Double.isNaN(h))
            return null;

        Point P2 = P1.sub(P0).scale(a/d).add(P0);
        double x3, y3, x4, y4;
        x3 = P2.x + h*(P1.y - P0.y)/d;
        y3 = P2.y - h*(P1.x - P0.x)/d;
        x4 = P2.x - h*(P1.y - P0.y)/d;
        y4 = P2.y + h*(P1.x - P0.x)/d;

        return new Point[]{new Point(x3, y3, 0), new Point(x4, y4, 0)};
    }

}

static class Sphere
{
    double x,y,z,r,left;
    Sphere(double x, double y, double z, double r)
    {
        this.x = x;
        this.y = y;
        this.z = z;
        this.r = r;
        left = x-r;
    }

    Circle intersection(Sphere s) 
    {
        Point P0 = new Point(x, y, z);
        Point P1 = new Point(s.x, s.y, s.z);

        double d, a, h;
        d = P0.distance(P1);
        a = (r*r - s.r*s.r + d*d)/(2*d);
        h = Math.sqrt(r*r - a*a);
        if(Double.isNaN(h))
            return null;

        Point P2 = P1.sub(P0).scale(a/d).add(P0);
        return new Circle(P2, h);
    }

    Point[] intersections(Circle c)
    {
        Point P0 = new Point(0,0,0);
        Point P1 = new Point(0,0,0);
        //...
        return new Point[]{P0, P1};
    }

}

我检查了this 链接和this 链接,但我无法理解它们背后的逻辑以及如何编码。

我尝试使用 ProGAL 库进行球-球-球相交,但生成的坐标是四舍五入的。我需要精确的结果。

【问题讨论】:

    标签: java algorithm 3d geometry


    【解决方案1】:

    可以肯定的是,您需要的是如何相交 3 个球体? 如果是这样,那么您当前的 circle 数据结构是无用的。 假设您要与 3 个球体相交:s1、s2、s3,s1 和 s2 的交点将是一个圆,您将与 s3 相交以获得最终结果,但请记住该圆不在 XoY 平面上,它的中心可能在任何 3D 坐标上,它将面向 3D 空间中的一个方向。要存储这样一个圆的信息,您需要 centerX 、 centerY 、 centerZ 、 radius 和一个称为 normal 的 3d 矢量。

    class Circle3D
    {
        Point center;
        double r;
        Point normal;
        ...
    }
    

    完成这个新类后,您可以使用它来存储有关 Sphere-Sphere 交点的信息。之后你必须实现 Sphere-Circle3D 交集:

    Circle3D Intersect(Sphere s1 , Sphere s2)
    {
         double d = dist(s1.center , center)
         double x = (d*d + s1.r*s1.r - s2.r*s2.r)/(2*d)
         Point normal = normalize(s2.Center - s1.Center)
         Point center = s1.center + x*normal;
         double radius = sqrt(s1.r*s1.r - x*x)
    
         return new Circle3D(center , radius , normal);
    }
    

    如果数学看起来很混乱,请不要惊慌,阅读此Page

    现在是 sphere-circle3D 相交的时间,为此:

    point[] Intersect(Sphere s , Circle3D c)
    {
        /*
          first we check if sphere even intersects with plane of c
          I assume you know how to implement some if these functions
        */
        if(GetDistanceOfPointFromPlane(s.center , new Plane(c.center , normal))>s.radius)
             return NULL;
    
        /*
          again we check possibility of avoiding math of intersection
        */
        point dir = Normalize(s.center - c.center);
        if(!DoesRayIntersectWithSphere(s , new Ray(c.center , c.radius*dir)))
            return NULL;
    
        /*
          this is the ugly part of code that unfortunately is deep trig math.
          you must describe sphere and circle equations in polar system , then
          you must solve sphere = circle
          I hope the link below be helpful 
        */  
    
    }
    

    这是上面水泥中提到的链接

    http://mathworld.wolfram.com/SphericalCoordinates.html

    【讨论】:

    • 我实际上需要这些球体的交集。这种方式似乎很容易。但是,如果计算三个球体的交点更容易,那对我来说会更好。
    • 我明白你的意思,你可以从数学上看。直接找到交点意味着求解具有三个方程(每个方程对应一个球体)和三个变量 (x,y,z) 的方程组。知道我是这么想的,这很有可能,我之前在考虑更多的几何知识。但是寻找求解方程组的算法。祝你好运:D。
    猜你喜欢
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多