知识点 - 几何模板 向量版

知识点 - 计算几何向量版

简版 包含基本向量操作

struct V {
  double x, y;
  V() {}
  void sc() { scanf("%lf%lf", &x, &y); }
  V(double a, double b) : x(a), y(b) { }
  V operator+(V o) { return V(x + o.x, y + o.y); }
  V operator-(V o) { return V(x - o.x, y - o.y); }
  double L() { return sqrt(x * x + y * y); }
  V N() {
    double l = L();
    return V(x / l, y / l);
  }
  V rot(double th) { return V(x * cos(th) - y * sin(th), x * sin(th) + y * cos(th)); }
  V operator*(double z) { return V(x * z, y * z); }
  double operator*(V o) { return x * o.x + y * o.y; }
  double operator|(V o) { return x * o.y - o.x * y; }
  void pr() { printf("%lf %lf\n", x, y); }
} p[maxn];

简版的凸包

bool cmpr(V const &a, V const &b) {//cmpr必要时加上长度排序
	V v1 = a - st[0], v2 = b - st[0];
	return (v1 | v2) < -eps;
}
vector<V> ch;
void getCH() {
	sort(st + 1, st + n, cmpr);
	ch.push_back(st[0]);
	rep(i, 1, n-1) {
		while (ch.size() > 1 && (st[i] - ch.back() | ch.back() - ch[ch.size() - 2]) < eps)ch.pop_back();
		ch.push_back(st[i]);
	}
}
int out(int x) { return x ? x - 1 : ch.size() - 1; }
int in(int x) { return x + 1 == (int)ch.size() ? 0 : x + 1; }

三维向量

const double PI = acos(-1.0);
struct V3 {
	db x, y, z;
	V3() {}
	V3(db xx, db yy, db zz) :x(xx), y(yy), z(zz) {}
	void sc() {scanf("%lf%lf%lf", &x, &y, &z);}
	db L() { return sqrt(x*x + y * y + z * z); }
	V3 N() { db l = L(); return V3(x / l, y / l, z / l); }
	V3 operator+(V3 o) { return V3(x + o.x, y + o.y,z+o.z); }
	V3 operator-(V3 o) { return V3(x - o.x, y - o.y,z-o.z); }
	V3 operator*(db zz) { return V3(x * zz, y * zz,z*zz); }
	db operator*(V3 o) { return x * o.x + y * o.y+z*o.z; }
	V3 operator|(V3 o) { return V3(y*o.z-z*o.y,z*o.x-x*o.z,x * o.y - o.x * y); }
};
const double eps = 1e-8;
int sgn(db x) {
	if (fabs(x) < eps)return 0;
	else if (x > 0)return 1;
	else return -1;
}
struct L3 {
	V3 s, e;
	L3() {}
	L3(V3 ss, V3 ee) :s(ss), e(ee) {}
	V3 rot(V3 n, db theta) {
		if (sgn(((s - n) | (e - n)).L()) == 0)return n;
		V3 f1 = (e - s) | (n - s);
		V3 f2 = (e - s) | (f1);
		db len = ((s - n) | (e - n)).L() / (s - e).L(); 
		f1 = f1.N()*len; f2 = f2.N() * len;
		V3 h = n + f2;
		V3 nn = h + f1;
		return h + ((n - h)*cos(theta)) + ((nn - h)*sin(theta));
	}

};

用复数的全功能版

//若想加速可以用上面的 V代替复数 可以加速2~5倍
/*
typedef V point;
V conj(V p) {return V(p.x, -p.y);}
double arg(V p) { return atan2(p.y, p.x); }
double norm(V p) { return p.L()*p.L(); }
double abs(V p) { return p.L(); }
*/
typedef complex<double>  point;
#define Decimal fixed<<setprecision(20)
#define PB push_back
#define EB emplace_back
#define X real();
#define Y imag();
#define curr(PP,i) PP[i]
#define next(PP,i) PP[(i+1)%PP.size()]
#define diff(PP,i) (next(PP,i)-curr(PP,i))
const double eps = 1e-7;
const double PI = acos(-1.0);
const double INF = 1e18;
int n;
vector<point> V;
double sumS,nowS,mx,mn;
double cross(const point& a, const point& b) {
	return imag(conj(a)*b);
}
double dot(const point& a, const point& b) {
	return real(conj(a)*b);
}
double area(const vector<point>& p) {
	double A = 0;
	F(i, p.size()) A += cross(curr(p, i), next(p, i));
	return A / 2.;
}
double triangleArea(V a, V b, V c) {
	return abs((a - b) | (a - c)) / 2.;
}
typedef pair<V, V> segment;
point projection(const segment &l, const point &p) {
	double t = (p - l.fi)*( l.fi - l.se) / norm(l.fi - l.se);
	return l.fi +  (l.fi - l.se)*t;
}
bool intersectSP(const segment &s, const point &p) {return abs(s.fi - p) + abs(s.se - p) - abs(s.se - s.fi) < eps;}
bool intersectLP(const segment &l, const point &p) { return eq((l.first - p) | (l.second - p), 0); }
bool intersectLL(const segment &l, const segment &m) {
	return eq((l.first - l.second) | (m.first - m.second),0) || eq((l.first - l.second) | (l.first - m.second),0);
}
bool intersectLS(const segment &l, const segment &s) {
	return ((l.first - l.second) | (s.first - l.first))*((l.first - l.second) | (s.second - l.first))<eps;
}
int ccw(point a, point b, point c) {
	b =b- a, c =c- a;
	if ((b | c) > 0)return 1;//counter-clockwise
	if ((b | c) < 0)return -1;
	if (b*c < 0)return 2;//b-a-c /c-a-b
	if (norm(b) < norm(c))return -2;//a-b-c/b-c-a
	return 0;//a-c-b/b-c-a
}
bool intersectSS(const segment &s, const segment &t) {
	return ccw(s.first, s.second, t.first)*ccw(s.first, s.second, t.first) <= 0 &&
		ccw(t.first, t.second, s.first)*ccw(t.first, t.second, s.second) <= 0;
}

double distancePP(const point  &a, const point  &b) { return abs(a - b); }
double distanceLP(const segment  &l, const point  &p) { return abs(p-projection(l,p)); }
double distanceSP(const segment  &s, const point  &p) { 
	const point r = projection(s, p);
	if (intersectSP(s, r))return abs(r - p);
	return min(abs(s.fi-p),abs(s.se-p));
}

point crosspoint(segment const &l, segment const &m) {
	double A = (l.second - l.first)|( m.second - m.first);
	double B = (l.second - l.first) | (l.second - m.first); 
	if (abs(A) < eps&&abs(B) < eps)return m.fi;//same line
	if (abs(A) < eps)return point(INF, INF);//parallel
	return m.fi +  (m.se - m.fi)*(B / A);
}
double angle(const point& a, const point& b) {
	auto tmp = abs(arg(a) - arg(b));
	return min(tmp, 2 * PI - tmp);
}
double angle(const segment &s1, const segment &s2) {
	return angle(s1.second - s1.first, s2.second - s2.first);
}

point reflection(const segment  &l, const point  &p) {return p + (projection(l, p)-p) * 2.;}

暂时只包含圆圆交

typedef V point;
struct circle
{
	point c;
	ld r, v;
	circle() {}
	circle(point c, ld r, ld v) :c(c), r(r), v(v) {}

	inline point pt(double a)
	{
		return point(c.x + cos(a)*r, c.y + sin(a)*r);
	}
};
int getCircleCircleIntersection(circle C1, circle C2, point &t1, point &t2)
{
	ld d = abs(C1.c - C2.c);
	if (dcmp(d) == 0)
	{
		if (dcmp(C1.r - C2.r) == 0) return -1;// same cir
		return 0;// include
	}
	if (dcmp(C1.r + C2.r - d) < 0) return 0;// disjoint
	if (dcmp(fabs(C1.r - C2.r) - d) > 0) return 0;// include
	ld a = arg(C2.c - C1.c);
	ld da = acos((C1.r*C1.r + d * d - C2.r*C2.r) / (2 * C1.r*d));
	point p1 = C1.pt(a - da), p2 = C1.pt(a + da);
	t1 = p1;
	if (p1 == p2) return 1;
	t2 = p2;
	return 2;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值