点积和叉积【计算集合】

先简单看一道几何的题目吧。

常见的空间几何公式:

1.俩点之间的距离sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1))

2.平面三角公式:p = (a+b+c)/2   S = sqrt(p*(p-a)*(p-b)*(p-c));

 一、在做几何问题时,经常会遇到精度问题。

在浮点运算时会产生精度误差,为了控制精度,一般设置一个偏差值eps,eps要大于浮点运算结果的不确定量,一般取1e-8;

比较2个浮点数时,不能直接用==判断相等,可以选择用dcmp()函数来判断;

const double eps = 1e-8;
int dcmp(double x,double y){
    if(fabs(x - y) < eps) return 0;
    else return x<y?-1:1;
}

二、点积和叉积。

点积(Dot product)编程时计算点积,并不需要知道θ。因为如果已知 A=(Ax,Ay),B=(Bx,By)那么就有:A•B=AxBx+AyBy。

double Dot(Vector A,Vector B){return A.x*B.x + A.y*B.y;}

叉积(Cross product)它的计算公式是:A×B=∣A∣∣B∣sinθ,其中θ 表示向量 A 旋转到向量 B 所经过的夹角。两个向量的叉积是一个带正负号的数值

double Cross(Vector A,Vector B){return A.x*B.y – A.y*B.x;}

点积应用:

1.判断A和B的夹角是钝角还是锐角。

2.求向量A的长度。

3.求向量A与B的夹角大小。

叉积应用:

1.判断A与B的方向关系。

  • 若 A×B>0,B 在 A 的逆时针方向;
  • 若 A×B<0,B 在 A 的顺时针方向;
  • 若 A×B=0,B 与 A 共线,可能是同方向的,也可能是反方向的。

2.计算俩向量构成的平行四边形又向面积。

3.计算三点构成的三角形的面积。

4.向量旋转。

5.用叉积检查俩个向量是否平行或重合。

问题描述:

平面上有 N 条直线,其中第 i 条直线是 y=Aix+Bi。

请计算这些直线将平面分成了几个部分。

输入描述

第一行包含一个整数 NNN。

以下 N 行,每行包含两个整数 Ai,Bi

其中,1≤N≤1000,−105≤Ai,Bi≤1051

输出描述

输出一个整数

思路:

我们可以先看第一条线和第二条线。第一条线可以把平面分成2半,第二条线如果与第一条线平行,则平面分成3个部分;如果不平行,有1个交点,则平面分成4个部分。

总结就是,每增加一条线,平面分割的增加数量 = 与先前直线的交点数 + 1;

#include<bits/stdc++.h>
using namespace std;
const int N = 1005;
double A[N], B[N];
int main(){
    int n;    cin>>n;
    pair<double, double> p;
    set<pair<double, double>> s;  //利用set自动去重功能筛选掉重边
    for(int i = 0; i < n; i++){
        cin >> p.first >> p.second ;
        s.insert(p);
    }
    int i = 0;  //将去重后的直线数据放回A,B数组
    set<pair<double, double> >::iterator it = s.begin();
    while(it != s.end()){
        A[i] = it -> first;
        B[i] = it -> second;
        it++, i++;
    }
    long long ans = 2;  //初始情况当只有一条直线时,有两个平面
    for(int i = 1; i < s.size(); i++){    //从下标1开始,也就是第二条直线
        set<pair< double,  double> > pos;  //记录第i条直线与先前的交点
        for(int j = 0; j <= i-1; j++){
            double a1 = A[i], b1 = B[i];
            double a2 = A[j], b2 = B[j];
            if(a1 == a2) continue;    //平行线无交点,跳出

            p.first = (b2-b1)/(a1-a2);  //交点的x坐标
            p.second = a1*(b2-b1)/(a1-a2) + b1; //交点的y坐标
            pos.insert(p);
        }
        ans += pos.size() + 1;  //与先前直线的交点数+1
    }
    printf("%d\n", ans);
    return 0;
}

题目描述

平面直角坐标系中有一个三角形, 请你求出它的面积。

输入描述

第一行输入一个T ,代表测试数据量

每组测试数据输入有三行,每行一个实数坐标 (x,y) 代表三角形三个顶点。

输出描述

输出一个实数表示三角形面积。结果保留2位小数,误差不超过 10−210^{-2}10−2

#include<bits/stdc++.h>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--){
        double x1,y1,x2,y2,x3,y3;
        cin>>x1>>y1>>x2>>y2>>x3>>y3;
        double ans = (x2 - x1) * (y3 - y1) - (y2 - y1)*(x3 - x1);
        printf("%.2f\n",ans*0.5);
    }
    return 0;
}

平面直角坐标系中有一个点 C 和一条直线 AB ,求点 C 和直线 AB 的位置关系。

输入描述

第一行输入一个 T ,代表测试数据量

每组测试数据输入有三行,每行一个实数坐标 (x,y) 分别代表 A,B,C 三个点。

输出描述

如果点 C 在直线 AB 上, 输出IN , 如果点 C 在直线 AB 左侧,输出L, 如果点 C 在直线 AB 右侧输出R

代码:

#include<bits/stdc++.h>
using namespace std;
const double eps = 1e-8;
double x,y,x2,y2,x3,y3;
int sgn(double x) {
	if(fabs(x) < eps) return 0;
	else return x<0 ? -1 : 1;
}
int check(){
	int a = sgn((x3-x)*(y2-y) - (y3 - y)*(x2 - x));
	if(a<0) return 1;
	if(a>0) return -1;
	return 0;
}
int main() {
	int t;
	cin>>t;
	while(t--) {
		cin>>x>>y>>x2>>y2>>x3>>y3;
		if(check() == 0) cout<<"IN"<<endl;
		else if(check() == 1) cout<<"L"<<endl;
		else cout<<"R"<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值