计算几何(1)——直线、点和向量

#include<bits/stdc++.h>
using namespace std;
#define RIGHT 1
#define ON 0
#define LEFT -1
const int maxn = 1e5 + 5;
using ull = unsigned long long;
using ldb = long double;
const ldb eps = 1e-10;
const ull mod = 1e9 + 7;
const ldb pi = acosl(-1);

struct poi {
	ldb x, y;
	poi(ldb a, ldb b) : x(a), y(b) {}
};
using vec = poi;

struct line {
	ldb k;
	ldb b;
	line(poi p, poi q) {
		k = (p.y - q.y) / (p.x - q.x);
		b = p.y - k * p.x;
	}
	line(ldb k_, ldb b_) : k(k_), b(b_) {}
	line(ldb k_, poi p) {
		k = k_;
		b = p.y - k * p.x;
	}
};

inline vec add(vec x1, vec x2) {
	return vec(x1.x + x2.x, x1.y + x2.y);
}

inline vec red(vec x1, vec x2) {
	return vec(x1.x - x2.x, x1.y - x2.y);
}

inline vec number_mul(vec v, ldb n) {//数量乘
	return vec(v.x / n, v.y / n);
}

inline ldb distance(poi a, poi b) {//距离
	vec tmp = red(a, b);
	return sqrtl(tmp.x * tmp.x + tmp.y * tmp.y);
}

inline ldb size(vec v) {//模
	return sqrtl(v.x * v.x + v.y * v.y);
}

inline ldb dot(vec x1, vec x2) {//点积
	return x1.x * x2.x + x1.y * x2.y;
}

inline ldb cross(vec v1, vec v2) {//叉积
	return v1.x * v2.y - v2.x * v1.y;
}

inline int sign(ldb x) {//符号
	if (fabsl(x) < eps) return ON;
	else if (x < eps) return LEFT;
	return RIGHT;
}

inline int equal(ldb a, ldb b) {
	return sign(a - b);
}

inline vec direction(vec v) {//单位方向向量
	return number_mul(v, size(v));
}

inline vec normal(vec v) {//单位法向量
	vec dir = direction(v);
	return vec(dir.y, dir.x);
}

inline ldb sin_of_angle_between_two_vectors(vec v1, vec v2) {//夹角正弦值
	return cross(v1, v2) / (size(v1) * size(v2));
}

inline ldb cos_of_angle_between_two_vectors(vec v1, vec v2) {//夹角余弦值
	return dot(v1, v2) / (size(v1) * size(v2));
}

inline ldb tan_of_angle_between_two_vectors(vec v1, vec v2) {//夹角正切值
	return cross(v1, v2) / dot(v1, v2);
}

inline vec projection_of_vector_onto_vector(vec v1, vec v2) {//向量投影至向量
	return number_mul(v1, dot(v1, v2));
}

inline line drop_perpendicular_form_point_to_line(line l, poi p) {//过一点向一线做垂线
	return line(-1 / l.k, p);
}

inline poi intersection(line l1, line l2) {//两直线交点
	ldb x = ((l2.b - l1.b) / (l1.k - l2.k));
	return poi(x, l1.k * x + l1.b);
}

inline poi projection_of_point_onto_line(line l, poi p) {//点到线的投影,即求垂足
	return intersection(drop_perpendicular_form_point_to_line(l, p), l);
}

inline vec direction(line l) {//直线方向向量
	return direction(vec(1, l.k));
}

inline vec normal(line l) {//直线法向量
	return direction(vec(l.k, 1));
}

inline vec projection_of_vector_onto_line(line l, vec v) {//向量投影至直线 的 投影
	return projection_of_vector_onto_vector(direction(l), v);
}

inline bool parallel(line l1, line l2) {//是否平行
	return !equal(l1.k, l2.k);
}

inline bool perpendicular(line l1, line l2) {//是否垂直
	return !equal(l1.k * l2.k, -1);
}

inline int position_of_point_and_line(line l,poi p) {//直线和点位置关系
	vec d = direction(l);
	return sign(cross(p,d));
}

int main() {
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值