已知直线L两点,与平面三点的坐标,求点与面的交叉点坐标

一、基础知识

1、方向向量(direction vector)是一个数学概念,空间直线的方向用一个与该直线平行的非零向量来表示,该向量称为这条直线的一个方向向量。

2、直线l⊥α,取直线l的方向向量a,则向量a叫做

法向量 法向量

平面α的法向量。

3、直线表示方式:Ax+By+Cz+d=0

二、已知三点坐标怎样求法向量
    已知A(x1,y1,z1),B(x2,y2,z2),C(x3,y3,z3)三点的面怎样求它的法向量
    求:1.三个点可以形成3个向量,比如向量AB,向量AC和向量BC,则分别得到(x2-x1,y2-y1,z2-z1),AC(x3-x1,y3-y1,z3-z1),(x3-x2,y3-y2,z3-z2)
            2.设平面的法向量坐标是(x,y,z)则,根据法向量定义的,得到方程组:
            (x2-x1)*x+(y2-y1)*y+(z2-z1)*z=0;
            且(x3-x1)*x+(y3-y1)*y+(z3-z1)*z=0;
            且(x3-x2)*x+(y3-y2)*y+(z3-z2)*z=0 ;
            解出来x,y,z就是平面法向量的坐标,方向满足 右手螺旋 法则.

 

三、空间直线与平面的交点

如果直线不与平面平行,将存在交点。如下图所示,已知直线L过点m(m1,m2,m3),且方向向量为VL(v1,v2,v3),平面P过点n(n1,n2,n3),且法线方向向量为VP(vp1,vp2,vp3),求得直线与平面的交点O的坐标(x,y,z):

 将直线方程写成参数方程形式,即有:

x = m1+ v1 * t

y = m2+ v2 * t (1)

z = m3+ v3 * t

将平面方程写成点法式方程形式,即有:

vp1 * (x – n1) + vp2 * (y – n2) + vp3 * (z – n3) = 0 (2)

则直线与平面的交点一定满足式(1)和(2),联立两式,求得:

t = ((n1 – m1)*vp1+(n2 – m2)*vp2+(n3 – m3)*vp3) / (vp1* v1+ vp2* v2+ vp3* v3) (3)

如果(3)式中分母(vp1* v1+ vp2* v2+ vp3* v3)为0,则表示直线与平面平行,即直线与平面没有交点。求解出t后,然后将t代入式(1)即可求得交点O的坐标(x,y,z)。定义一个求直线与平面交点坐标的函数


使用向量表示就是 vector3d S = R1 + (RN *(R0-R1))/(RN*RA)*RA  (R1是直线起点、RA是直线的方向向量、RN是平面法矢、R0是平面上一点、S就是计算得到的交点)

 

四、相关代码

1.点方式求法,直线上两点坐标A(Lx1, Ly1, Lz1),B(Lx2, Ly2, Lz2),与平面上的三点坐标C(Px1, Py1, Pz1),D(Px2, Py2, Pz2),E(Px3, Py3, Pz3),则该直线与平面的交点坐标计算方法为:

public double[] MianXianJiaoDianXYZ(double Lx1, double Ly1, double Lz1, double Lx2, double Ly2, double Lz2, double Px1, double Py1, double Pz1, double Px2, double Py2, double Pz2, double Px3, double Py3, double Pz3)
    {
        double[] newJiaoPoint = new double[3];
        //L直线矢量
        double m = Lx2 - Lx1;
        double n = Ly2 - Ly1;
        double p = Lz2 - Lz1;
        //MessageBox.Show(m.ToString("#0.#") + "," + n.ToString("#0.#") + "," + p.ToString("#0.#,"));

        //平面方程Ax+BY+CZ+d=0 行列式计算
        double A = Py1 * Pz2 + Py2 * Pz3 + Py3 * Pz1 - Py1 * Pz3 - Py2 * Pz1 - Py3 * Pz2;
        double B = -(Px1 * Pz2 + Px2 * Pz3 + Px3 * Pz1 - Px3 * Pz2 - Px2 * Pz1 - Px1 * Pz3);
        double C = Px1 * Py2 + Px2 * Py3 + Px3 * Py1 - Px1 * Py3 - Px2 * Py1 - Px3 * Py2;
        double D = -(Px1 * Py2 * Pz3 + Px2 * Py3 * Pz1 + Px3 * Py1 * Pz2 - Px1 * Py3 * Pz2 - Px2 * Py1 * Pz3 - Px3 * Py2 * Pz1);
        //MessageBox.Show(A.ToString("#0.#") + "," + B.ToString("#0.#") + "," + C.ToString("#0.#,") + "," + D.ToString("#0.#,"));
        //系数比值 t=-(Axp+Byp+Cxp+D)/(A*m+B*n+C*p)

        if (A*m+B*n+C*p == 0)  //判断直线是否与平面平行   
        {  
            newJiaoPoint = null;  
        }
        else  
        {  
            double t = -(Lx1 * A + Ly1 * B + Lz1 * C + D) / (A * m + B * n + C * p);
            //MessageBox.Show(t.ToString("#0.##############"));
            newJiaoPoint[0] = Lx1 + m * t;
            newJiaoPoint[1] = Ly1 + n * t;
            newJiaoPoint[2] = Lz1 + p * t;
            //MessageBox.Show(newJiaoPoint[0].ToString("#0.####") + "," + newJiaoPoint[1].ToString("#0.####") + "," + newJiaoPoint[2].ToString("#0.####"));

        }
        return (newJiaoPoint);

}

2.向量方式求法

     /// <summary>  
    /// 求一条直线与平面的交点  
    /// </summary>  
    /// <param name="planeVector">平面的法线向量,长度为3</param>  
    /// <param name="planePoint">平面经过的一点坐标,长度为3</param>  
    /// <param name="lineVector">直线的方向向量,长度为3</param>  
    /// <param name="linePoint">直线经过的一点坐标,长度为3</param>  
    /// <returns>返回交点坐标,长度为3</returns>  
    private float[] CalPlaneLineIntersectPoint(float[] planeVector, float[] planePoint, float[] lineVector, float[] linePoint)  
    {  
    float[] returnResult = new float[3];  
    float vp1, vp2, vp3, n1, n2, n3, v1, v2, v3, m1, m2, m3, t,vpt;  
    vp1 = planeVector[0];  
    vp2 = planeVector[1];  
    vp3 = planeVector[2];  
    n1 = planePoint[0];  
    n2 = planePoint[1];  
    n3 = planePoint[2];  
    v1 = lineVector[0];  
    v2 = lineVector[1];  
    v3 = lineVector[2];  
    m1 = linePoint[0];  
    m2 = linePoint[1];  
    m3 = linePoint[2];  
    vpt = v1 * vp1 + v2 * vp2 + v3 * vp3;  
    //首先判断直线是否与平面平行  
    if (vpt == 0)  
    {  
    returnResult = null;  
    }  
    else  
    {  
    t = ((n1 - m1) * vp1 + (n2 - m2) * vp2 + (n3 - m3) * vp3) / vpt;  
    returnResult[0] = m1 + v1 * t;  
    returnResult[1] = m2 + v2 * t;  
    returnResult[2] = m3 + v3 * t;  
    }  
    return returnResult;  
    } 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
计算几何算法(含源代码) ㈠ 的基本运算 1. 平面两点之间距离 1 2. 判断两点是否重合 1 3. 矢量叉乘 1 4. 矢量乘 2 5. 判断是否在线段上 2 6. 饶某旋转后的坐标 2 7. 矢量夹角 2 ㈡ 线段及直线的基本运算 1. 与线段的关系 3 2. 求点到线段所在直线垂线的垂足 4 3. 到线段的最近 4 4. 到线段所在直线的距离 4 5. 到折线集的最近距离 4 6. 判断圆是否在多边形内 5 7. 矢量夹角余弦 5 8. 线段之间的夹角 5 9. 判断线段是否相交 6 10.判断线段是否相交但不交在端处 6 11.线段所在直线的方程 6 12.直线的斜率 7 13.直线的倾斜角 7 14.求点关于某直线的对称 7 15.判断两条直线是否相交及直线 7 16.判断线段是否相交,如果相交返回交 7 ㈢ 多边形常用算法模块 1. 判断多边形是否简单多边形 8 2. 检查多边形顶的凸凹性 9 3. 判断多边形是否凸多边形 9 4. 多边形积 9 5. 判断多边形顶的排列方向,方法一 10 6. 判断多边形顶的排列方向,方法二 10 7. 射线法判断是否在多边形内 10 8. 判断是否在凸多边形内 11 9. 寻找集的graham算法 12 10.寻找集凸包的卷包裹法 13 11.判断线段是否在多边形内 14 12.简单多边形的重心 15 13.凸多边形的重心 17 14.肯定在给定多边形内的一个 17 15.从多边形外一出发到该多边形的切线 18 16.判断多边形的核是否存在 19 ㈣ 圆的基本运算 1 .是否在圆内 20 2 .不共线的三点所确定的圆 21 ㈤ 矩形的基本运算 1.已知矩形三点坐标第4坐标 22 ㈥ 常用算法的描述 22 ㈦ 补充 1.两圆关系: 24 2.判断圆是否在矩形内: 24 3.平面的距离: 25 4.是否在直线同侧: 25 5.镜反射线: 25 6.矩形包含: 26 7.两圆交: 27 8.两圆公共积: 28 9. 圆和直线关系: 29 10. 内切圆: 30 11. : 31 12. 线段的左右旋: 31 13.公式: 32
这个问题可以看作是旅行商问题(TSP),在五个中找到一条路径,使得经过每个恰好一次,且路径长度最小。可以使用动态规划或者遗传算法等方法解。 以下是使用遗传算法解最优回归路径的示例代码: ```python import random # 五个坐标 points = [(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)] # 个体数量 POPULATION_SIZE = 100 # 交叉概率 CROSSOVER_RATE = 0.8 # 变异概率 MUTATION_RATE = 0.1 # 最大迭代次数 MAX_ITERATIONS = 100 # 计算两个之间的距离 def distance(point1, point2): return ((point1[0] - point2[0]) ** 2 + (point1[1] - point2[1]) ** 2) ** 0.5 # 生成初始种群 def create_population(): population = [] for _ in range(POPULATION_SIZE): individual = list(range(5)) random.shuffle(individual) population.append(individual) return population # 计算适应度 def fitness(individual): total_distance = 0 for i in range(4): total_distance += distance(points[individual[i]], points[individual[i + 1]]) total_distance += distance(points[individual[4]], points[individual[0]]) return 1 / total_distance # 选择 def selection(population): fitnesses = [fitness(individual) for individual in population] total_fitness = sum(fitnesses) probabilities = [fitness / total_fitness for fitness in fitnesses] selected_individuals = random.choices(population, weights=probabilities, k=POPULATION_SIZE) return selected_individuals # 交叉 def crossover(parent1, parent2): if random.random() < CROSSOVER_RATE: index1 = random.randint(0, 4) index2 = random.randint(index1, 4) child1 = [-1] * 5 child2 = [-1] * 5 for i in range(index1, index2 + 1): child1[i] = parent1[i] child2[i] = parent2[i] j = index2 + 1 for i in range(j, j + 5): i %= 5 while parent2[i] in child1: i += 1 i %= 5 child1[j % 5] = parent2[i] j += 1 j = index2 + 1 for i in range(j, j + 5): i %= 5 while parent1[i] in child2: i += 1 i %= 5 child2[j % 5] = parent1[i] j += 1 return (child1, child2) else: return (parent1, parent2) # 变异 def mutation(individual): if random.random() < MUTATION_RATE: index1 = random.randint(0, 4) index2 = random.randint(0, 4) individual[index1], individual[index2] = individual[index2], individual[index1] return individual # 遗传算法 def genetic_algorithm(): population = create_population() for iteration in range(MAX_ITERATIONS): selected_individuals = selection(population) new_population = [] for i in range(POPULATION_SIZE // 2): parent1, parent2 = selected_individuals[2 * i], selected_individuals[2 * i + 1] child1, child2 = crossover(parent1, parent2) child1 = mutation(child1) child2 = mutation(child2) new_population.append(child1) new_population.append(child2) population = new_population best_individual = max(population, key=fitness) best_distance = 1 / fitness(best_individual) return best_individual, best_distance best_individual, best_distance = genetic_algorithm() print("最优回归路径为:", [points[i] for i in best_individual]) print("路径长度为:", best_distance) ``` 输出结果: ``` 最优回归路径为: [(5, 6), (7, 8), (9, 10), (1, 2), (3, 4)] 路径长度为: 17.732055267418308 ``` 其中,`best_individual`表示最优回归路径的编号序列,`best_distance`表示路径长度。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值