四点共面(混合积 " x " 乘 与 " . ”乘)

四点共面

给出三维空间上的四个点(点与点的位置均不相同),判断这4个点是否在同一个平面内(4点共线也算共面)。如果共面,输出”Yes”,否则输出”No”重点内容。

Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)
第2 - 4T + 1行:每行4行表示一组数据,每行3个数,x, y, z, 表示该点的位置坐标(-1000 <= x, y, z <= 1000)。

Output**
输出共T行,如果共面输出”Yes”,否则输出”No”。

Sample Input
1
1 2 0
2 3 0
4 0 0
0 0 0

Sample Output
Yes

该题的 思路 就是 根据 向量积 和 数量积 ,在这里 简单的 复习一下 所谓 向量积 的 就是 标题 所说的 两个 向量 的“X” 乘,其计算后的 结果 是得到 一个 与 前面 进行 运算的 两个 向量 所 确定的 平面的 一个 法向量; 所谓 数量积 就是 两个向量 的 对应 坐标 的乘积 的 和 ,计算结果 是一个 数,如果 两个 向量 垂直的话 ,那么 数量积 == 0. 所谓 混合积 呢 就是 向量积 和 数量积 的 综合 运算 。

下面 这个 代码 是 创建一个 结构是 结构体 里面的 代码 ,它的 作用是 重载 operator 后面的 那个一 “-”号 是 重载 相当于 是 要读取的 符号 ,这样说的 话 不太好理解 ,我举一个例子 : 对于 spot[1] - spot[2], 减号左右两边 都是 一个 结构体,我们知道 结构体 是可以 直接 进行 赋值的(spot[1] = spot[2]) 但是 不能 直接进行 加减乘除 等 运算, 那么 下面 那个 程序 就发挥啦 他神奇 的作用啦 ,我们 模拟一下 运算过程 下面 的 this 表示 spot[1] 然后 检测 到 spot[1] 后面的 是 减号“-”,然后可以 调用 下面的 重载 程序 把 spot[2] 当作 参数 传递 进来 变成啦 &o 然后 经过 运算之后 返回啦 一个 结构体 赋值给 啦 整个 表达式 “spot[1] - spot[2]”这个 表达式 就相当于 一个 结构体 变量 可以 进行 下面的 其他 运算 。

SPOT  operator - (SPOT &o)
    {
        SPOT  ans;
        ans.x = this->x - o.x;
        ans.y = this->y - o.y;
        ans.z = this->z - o.z;
        return ans;
    }

如果 上面的 重载 代码 理解啦 现在 我们 再来 简单的 改变一下它的 功能 : 大家 猜一下 下面的结果 是不是一样?

//  differ  one   运算式 : spot[1] - spot[2]
SPOT  operator - (SPOT &o)
    {
        SPOT  ans;
        ans.x = this->x + o.x;
        ans.y = this->y + o.y;
        ans.z = this->z + o.z;
        return ans;
    }
//  differ  two   运算式 : spot[1] + spot[2]
SPOT  operator + (SPOT &o)
    {
        SPOT  ans;
        ans.x = this->x - o.x;
        ans.y = this->y - o.y;
        ans.z = this->z - o.z;
        return ans;
    }

第一个 表达式 实际上 是 进行啦 加法运算, 第二个 实际上 是进行啦 减法 运算 ,大家 是不是 明白啦 什么 呢?(~ ? ~)!!
对啦 大家 有可能 回想 &o 前面的 取值符 是干什么呢 ?其实 把 在这里 是没有用的 , 可以 去掉 ,其实 它的 作用 就是 把 进行运算的的结构体的 地址 传递过来 ,可以 对 传递进来的 结构体 的内容进行 改变。

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;

struct SPOT
{
    double x;
    double y;
    double z;
    SPOT  operator - (SPOT &o)
    {
        SPOT  ans;
        ans.x = this->x - o.x;
        ans.y = this->y - o.y;
        ans.z = this->z - o.z;
        return ans;
    }
};
/**
*   计算 两个 空间 向量的 数量积
*/
double dot_product(const SPOT &a, const SPOT &b)
{
    return a.x*b.x + a.y*b.y + a.z*b.z;
}
/**
*  计算  两个 空间向量 的 向量 积 
*/
SPOT cross_product(const SPOT &a, const SPOT &b)
{
    SPOT ans;
    ans.x = a.y * b.z - a.z * b.y;
    ans.y = a.z * b.x - a.x * b.z;
    ans.z = a.x * b.y - a.y * b.x;
    return ans;
}
/**
* 主函数 的 整体 思路 大概 根据 就是 根据 三个 向量的 混合积  == 0  进行判断的
*/

int main()
{
    int t;
    SPOT spot[4];
    while(scanf("%d", &t) != EOF)
    {
        while(t--)
        {
            for(int i = 0; i < 4; i++)
                scanf("%lf%lf%lf", &spot[i].x, &spot[i].y, &spot[i].z);
            double temp = dot_product(spot[3] - spot[0], cross_product(spot[2] - spot[0], spot[1] - spot[0]));
            if(temp >= 0.0 && temp <= 1e-8)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值