已知空间三点组成的面求该面上某点的Z值

已知空间三点,那么可以就可以确定空间三点组成的平面。此时可以根据某一点的X值和Y值,来求取该点在平面上的Z值。这个过程对于求三角面片上某点的高程或者权值特别有用,其本身也可以看作一种线性插值。

其算法思路也特别简单,首先算出其三点组成的平面法向量(可参看《已知三点求平面法向量》);然后根据平面法向量\(n=(A,B,C)\)和平面上某点\(m=(x0,y0,z0)\),有平面的点法式方程:
\[ A(X-x0)+B(Y-y0)+C(Z-z0)=0 \]
最后根据欲求点的X、Y值,代入公式解算Z值即可。

具体实现代码如下:

#include<iostream>

using namespace std;

//三维double矢量
struct Vec3d
{
    double x, y, z;

    Vec3d()
    {
        x = 0.0;
        y = 0.0;
        z = 0.0;
    }
    Vec3d(double dx, double dy, double dz)
    {
        x = dx;
        y = dy;
        z = dz;
    }
    void Set(double dx, double dy, double dz)
    {
        x = dx;
        y = dy;
        z = dz;
    }
};

//计算三点成面的法向量
void Cal_Normal_3D(const Vec3d& v1, const Vec3d& v2, const Vec3d& v3, Vec3d &vn)
{
    //v1(n1,n2,n3);
    //平面方程: na * (x – n1) + nb * (y – n2) + nc * (z – n3) = 0 ;
    double na = (v2.y - v1.y)*(v3.z - v1.z) - (v2.z - v1.z)*(v3.y - v1.y);
    double nb = (v2.z - v1.z)*(v3.x - v1.x) - (v2.x - v1.x)*(v3.z - v1.z);
    double nc = (v2.x - v1.x)*(v3.y - v1.y) - (v2.y - v1.y)*(v3.x - v1.x);

    //平面法向量
    vn.Set(na, nb, nc);
}

void CalPlanePointZ(const Vec3d& v1, const Vec3d& v2, const Vec3d& v3, Vec3d& vp)
{
    Vec3d vn;
    Cal_Normal_3D(v1, v2, v3, vn);  

    if (vn.z != 0)              //如果平面平行Z轴
    {
        vp.z = v1.z - (vn.x * (vp.x - v1.x) + vn.y * (vp.y - v1.y)) / vn.z;         //点法式求解
    }
}

int main()
{
    Vec3d v1(1.0, 5.2, 3.7);
    Vec3d v2(2.8, 3.9, 4.5);
    Vec3d v3(7.6, 8.4, 6.2);
    Vec3d vp;
    v3.x = 5.6;
    v3.y = 6.4;
    v3.z = 0.0;

    CalPlanePointZ(v1, v2, v3, vp);

    return 0;
}

原文地址:https://www.cnblogs.com/charlee44/p/12109904.html

时间: 2024-08-09 10:03:49

已知空间三点组成的面求该面上某点的Z值的相关文章

已知空间三个点,解算外接圆圆心坐标,C++编程实现

struct PT3 { double x, y, z; }; int solveCenterPointOfCircle(std::vector<PT3> pt, double centerpoint[]) { double a1, b1, c1, d1; double a2, b2, c2, d2; double a3, b3, c3, d3; double x1 = pt[0].x, y1 = pt[0].y, z1 = pt[0].z; double x2 = pt[1].x, y2 =

POJ 2208 已知空间四面体六条边长度,求体积

Pyramids Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2718   Accepted: 886   Special Judge Description Recently in Farland, a country in Asia, a famous scientist Mr. Log Archeo has discovered ancient pyramids. But unlike those in Egyp

已知圆心,半径,角度,求圆上的点坐标

圆点坐标:(x0,y0) 半径:r 角度:a0 则圆上任一点为:(x1,y1) x1   =   x0   +   r   *   cos(ao   *   3.14   /180   ) y1   =   y0   +   r   *   sin(ao   *   3.14   /180   ) 已知圆心,半径,角度,求圆上的点坐标

已知三角形三边长求面积

不知道有没有问题…… #include<stdio.h> #include<math.h> #include<conio.h> float areatri(float a,float b,float c); float main() { float a,b,c; float s; char d; loop: printf("输入三角形三边长,以空格隔开\n"); scanf("%f %f %f",&a,&b,&am

已知二叉树前序和中序,求二叉树。

如题,给出二叉树的前序遍历和中序遍历,怎么还原二叉树. 假如一个二叉树的前序遍历为:12453,中序遍历为:42513.由于这颗二叉树比较简单,可以用 凑 的方法很容易凑出符合题意的二叉树(没有写这篇文章之前,我都是用这种笨方法的..尴尬). 即如图: 那么有没有一个标准的方法来推导呢?当然是有的! 我们来分析一下这棵树的前序和中序. 先看前序:12453,第一个字符"1"肯定是整棵树root节点,这不用解释.至于第二个字符以及往后的字符就没有什么可用的信息了. 再看中序:42513,

已知六条边的边长,求四面体体积

Problem Description 杭州电子科技大学即将迎来50周年的校庆,作为校庆委员会成员的我被上级要求设计一座神秘的建筑物来迎合校庆,因此我苦思冥想了一个月,终于设计出了一套方案,这座建筑物有点象古老埃及的金字塔,不过这个神秘建筑的根基是三角形的而不是矩形的,从数学的专业角度来讲,它是四面体.当我打算上交我的设计图纸的时候发现,我不知道怎么计算这个神秘建筑的体积(我知道这座建筑的各边的尺寸),于是我找来了聪明的你来帮助我解决这个难题. Input 输入文件包含6个不超过1000的实数,

已知某一天是周几 求给定的一天是周几的算法 C++实现

#include<iostream> using namespace std; struct Date{ int year,month,day; }; enum Week{ MON=1, TUE, WED, THU, FRI, SAT, SUN, }; int isLeapYear(int y) { if((y%4==0&&y%100!=0)||y%400==0)return 1; else return 0; } int DaysGone(Date d,int *restda

C++ 已知两个时间(年月日)求日期差

#include<iostream> #include <ctime> using namespace std; int main() { struct tm t1 = { 0 }; struct tm t2 = { 0 }; double seconds; t1.tm_year = 2019 - 1900; t1.tm_mon = 6; t1.tm_mday = 6;//现在时间2019,7,6 t2.tm_year = 2020 - 1900; t2.tm_mon = 5; t

已知正方形对角线两点求另外两点

正方形,已知 (x0,y0) 和(x2,y2)  可以根据下列关系求(x1,y1),(x3,y3) x1+x3 = x0+x2; x1-x3  =  y2-y0; y1+y3 =  y0+y2; y1-y3 =  x0-x2; node[0].p[1].x = ((node[0].p[0].x+node[0].p[2].x)+(node[0].p[2].y-node[0].p[0].y))/2; node[0].p[1].y = ((node[0].p[0].y+node[0].p[2].y)+