java判断三维直线是否相交

因为工作需要,在网上找了很多的资料,没有直接的方法来解释或者是判断三维直线如何相交的问题。

对于初学者(伸手党)来说很是苦扰。转载需要说明

这里我自己尝试写了一下demo,感觉还是不错,但是只能判断三维无限长度的直线是否相交。

如果是有限长度的三维直线,那么这个方式就不适用了,需要自己判断交点。

原理:我这里是使用向量的方式来求的

如:空间直线段1,2

1、获取线段1的方向向量

2、获取线段2的方向向量

3、获取方向向量的阶乘

4、从线段1任取一点,线段2任取一点组成一向量,相乘判断n的值就能判断是否相交

好了原理大致这样略过,no code say bb?

public class Distance3dTest
{
    public String test3d(String point1, String point2,String point3,String point4)
    {
        //注意这里是包含有xyz坐标系的
        Point3d p1 = new Point3d(point1);
        Point3d p2 = new Point3d(point2);
        Point3d p3 = new Point3d(point3);
        Point3d p4 = new Point3d(point4);

        //求出方向1的方向向量
        Point3d f1 = new Point3d();
        f1.setX(p2.x - p1.x);
        f1.setY(p2.y - p1.y);
        f1.setZ(p2.z - p1.z);

        //求出方向2的方向向量
        Point3d f2 = new Point3d();
        f2.setX(p4.x - p3.x);
        f2.setY(p4.y - p3.y);
        f2.setZ(p4.z - p3.z);


        if (f1.x * f2.y * f2.z == f2.x * f1.y * f1.z)
        {
            return "空间线段平行";
        }
        //法向量的阶乘
        Point3d faJie = faFa(f1, f2);

        //各取一点组成向量
        Point3d point3d = new Point3d();
        point3d.setX(p3.x-p1.x);
        point3d.setY(p3.y-p1.y);
        point3d.setZ(p3.z-p1.z);

        double n = point3d.x * faJie.x + point3d.y * faJie.y + point3d.z * faJie.z;
        if (n == 0)
        {
            return "相交!";
        }

        return "不相交";
    }

    /**
     * 2个法向量的叉乘
     */
    private Point3d faFa(Point3d p1,Point3d p2)
    {
        Point3d p = new Point3d();
        p.setX(p1.y * p2.z - p2.y * p1.z);
        p.setY(-(p1.x * p2.z - p2.x * p1.z));
        p.setZ(p1.x * p2.y - p2.x * p1.y);
        return p;
    }

    @Test
    public void test()
    {
        String s = test3d("0,0,0", "1,1,1", "1,1,2", "1,2,3");
        System.out.println(s+"============");
    }
}
public class Point3d
{
    public double x;
    public double y;
    public double z;

    public double getX()
    {
        return x;
    }

    public void setX(double x)
    {
        this.x = x;
    }

    public double getY()
    {
        return y;
    }

    public void setY(double y)
    {
        this.y = y;
    }

    public double getZ()
    {
        return z;
    }

    public void setZ(double z)
    {
        this.z=z;
    }

    public Point3d() {}
    public Point3d(String location)
    {
        super();
        //这里是我本地测试为了方便,传入的数据的类型是  1,2,3(经度,维度,高度,当然也可以自己赋值)
        String[] p1 = location.split(",");
        this.x = Double.valueOf(p1[0]);
        this.y = Double.valueOf(p1[1]);
        this.z = Double.valueOf(p1[2]);
    }
}

好了,基本上就这样判断。求交点比较的麻烦,这里因为我工作暂时不需要,所以也就没有深入的去了解,上面的代码如果高数学的好的话,基本上没多大问题,其实我就是利用高数推导出来的

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的 C++ 函数,用于判断两条三维线段是否相交: ```cpp #include <iostream> #include <cmath> using namespace std; struct Point3D { double x, y, z; }; bool isIntersected(Point3D p1, Point3D p2, Point3D p3, Point3D p4) { Point3D p13, p43, p21; double d1343, d4321, d1321, d4343, d2121; double numer, denom; const double EPSILON = 0.0000001; p13.x = p1.x - p3.x; p13.y = p1.y - p3.y; p13.z = p1.z - p3.z; p43.x = p4.x - p3.x; p43.y = p4.y - p3.y; p43.z = p4.z - p3.z; if (fabs(p43.x) < EPSILON && fabs(p43.y) < EPSILON && fabs(p43.z) < EPSILON) return false; p21.x = p2.x - p1.x; p21.y = p2.y - p1.y; p21.z = p2.z - p1.z; if (fabs(p21.x) < EPSILON && fabs(p21.y) < EPSILON && fabs(p21.z) < EPSILON) return false; d1343 = p13.x * p43.x + p13.y * p43.y + p13.z * p43.z; d4321 = p43.x * p21.x + p43.y * p21.y + p43.z * p21.z; d1321 = p13.x * p21.x + p13.y * p21.y + p13.z * p21.z; d4343 = p43.x * p43.x + p43.y * p43.y + p43.z * p43.z; d2121 = p21.x * p21.x + p21.y * p21.y + p21.z * p21.z; denom = d2121 * d4343 - d4321 * d4321; if (fabs(denom) < EPSILON) return false; numer = d1343 * d4321 - d1321 * d4343; double mua = numer / denom; double mub = (d1343 + d4321 * mua) / d4343; Point3D pa, pb; pa.x = p1.x + mua * p21.x; pa.y = p1.y + mua * p21.y; pa.z = p1.z + mua * p21.z; pb.x = p3.x + mub * p43.x; pb.y = p3.y + mub * p43.y; pb.z = p3.z + mub * p43.z; double dist = sqrt((pa.x - pb.x) * (pa.x - pb.x) + (pa.y - pb.y) * (pa.y - pb.y) + (pa.z - pb.z) * (pa.z - pb.z)); if (dist < EPSILON) return true; else return false; } int main() { Point3D p1 = {0, 0, 0}; Point3D p2 = {1, 1, 1}; Point3D p3 = {0, 1, 0}; Point3D p4 = {1, 0, 1}; if (isIntersected(p1, p2, p3, p4)) { cout << "The two line segments intersect." << endl; } else { cout << "The two line segments do not intersect." << endl; } return 0; } ``` 该函数的输入是两个三维线段的端点坐标,输出是一个布尔值,表示它们是否相交。如果相交,返回 `true`,否则返回 `false`。 该函数使用了两条线段的参数方程,通过求解它们的交点来判断它们是否相交。如果交点在两条线段之间,则它们相交,否则它们不相交。 该函数还考虑了一些特殊情况,例如两条线段重合、平行、退化为点或直线等。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值