日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

算法学习:计算几何旋转卡壳

發布時間:2025/7/14 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 算法学习:计算几何旋转卡壳 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【定義】

【對踵點】多邊形上存在平行切線的兩點

【多邊形半徑】多邊形上任意兩點的最大長度

?


【旋轉卡殼】

?選取y軸上,最高和最低的兩個點,令兩條平行于x軸的線切過這兩點

?然后我們開始讓這兩條線旋轉

?當一條線首先和多邊形上一條線段平行時,另外一條邊也會停止旋轉

?這個時候,就需要通過叉乘來判斷現在取得對點是否符合要求

?即,擁有平行的切線

此處我們用另外一種方法來找到,當前點所對應的最遠點(向量的證明還不會QAQ)

確定一條邊,然后按逆時針求這個點和這條邊組成的三角形的面積

當這個面積最大時,這個點就是最遠點

(此處我們找的是,離這條線段最遠的點)

?

?需要注意下最初比較選取時,各個值的賦值(我就因為這個浪費了兩個小時QAQ)

l max_dis(P* p) {int maxp = 1, minp = 1;ll maxy =-1001, miny = 1001;for (int i = 1; i <=n; i++){if (p[i].y > maxy) maxy = p[i].y, maxp = i;if (p[i].y < miny )miny = p[i].y, minp = i;}ll ans = max(dis(p[minp],p[maxp]),dis(p[(minp%n)+1],p[maxp]));for (int i = 1; i <=n; i++,minp=(minp+1>n)?1:(minp+1)){while (cross(p[(minp%n) + 1], p[(maxp % n)+1], p[minp]) > cross(p[(minp%n) + 1], p[maxp], p[minp]))maxp = (maxp+1) %n;ans = max(ans, dis(p[minp], p[maxp]));ans = max(ans, dis(p[(minp % n) +1], p[maxp]));}return ans; } View Code

?


模板題:

【POJ 2178】

?給定多邊形,求多邊形的半徑

?

#include<cstdio> #include<vector> #include<iostream> #include<algorithm> #include<map> #include<cmath> #define ll int using namespace std; const ll eps = 0; const int MAXN = 50010; const ll INF = (1<<31)-1; const ll lim = 100010; int n; struct V {ll x, y;V(ll a = 0, ll b = 0) :x(a), y(b) {} }; typedef V P; V operator+(V a, V b) { return V(a.x + b.x, b.y + a.y); } V operator-(V a, V b) { return V(a.x - b.x, b.y - a.y); } V operator*(V a, ll b) { return V(a.x*b, a.y*b); } V operator*(ll a, V b) { return V(a*b.x, b.y*a); } V operator/(V a, ll b) { return V(a.x / b, a.y / b); } V operator/(ll a, V b) { return V(b.x / a, b.y / a); } ll operator^(V a, V b) { return a.x*b.x + a.y*b.y; } bool operator<(V a, V b) { return (a.x == b.x) ? a.y < b.y : a.x < b.x; } int sgn(ll x) {return (x > eps) - (x < eps); } ll cross(V a, V b) {return a.x*b.y - b.x*a.y; } ll cross(P a, P b, P c) {return cross(b - a, c - a); } ll dis(V a) {return a ^ a; } ll dis(P a, P b) {return (dis(b - a)); } P ans[MAXN], s[MAXN]; P p[MAXN]; P* convex(P* l) {sort(l+1, l+1+n);P tmp(lim, lim);int pos = 0;int top = 0;for (int i = 1; i <=n; i++)if (l[i] < tmp)tmp = l[i], pos = i;for (int i = pos, cnt_ = 0; cnt_ < n; cnt_++, i =(i+1>n)?1:i+1){while (top >= 2 && sgn(cross(s[top-2], s[top-1], l[i])) <= 0)top--;s[top] = l[i]; top++;pos = i;}int cnt = 0;for (int i = 0; i < top; i++){cnt++;ans[cnt] = s[i];}top = 0;for (int i = pos, cnt_ = 0; cnt_ < n; cnt_++, i = (i - 1<1)?n:i-1){while (top >= 2 && sgn(cross(s[top - 2], s[top - 1], l[i])) <= 0)top--;s[top] = l[i]; top++;pos = i;}for (int i = 1; i + 1 < top; i++){cnt++;ans[cnt] = s[i];}n = cnt;return ans; } ll max_dis(P* p) {int maxp = 1, minp = 1;ll maxy =-1001, miny = 1001;for (int i = 1; i <=n; i++){if (p[i].y > maxy) maxy = p[i].y, maxp = i;if (p[i].y < miny )miny = p[i].y, minp = i;}ll ans = max(dis(p[minp],p[maxp]),dis(p[(minp%n)+1],p[maxp]));for (int i = 1; i <=n; i++,minp=(minp+1>n)?1:(minp+1)){while (cross(p[(minp%n) + 1], p[(maxp % n)+1], p[minp]) > cross(p[(minp%n) + 1], p[maxp], p[minp]))maxp = (maxp+1) %n;ans = max(ans, dis(p[minp], p[maxp]));ans = max(ans, dis(p[(minp % n) +1], p[maxp]));}return ans; } int main() {scanf("%d", &n);for (int i = 1; i <= n; i++){P tmp;scanf("%d%d", &tmp.x, &tmp.y);p[i] = tmp;}printf("%d", max_dis(convex(p)));return 0; } View Code

?

轉載于:https://www.cnblogs.com/rentu/p/11272517.html

總結

以上是生活随笔為你收集整理的算法学习:计算几何旋转卡壳的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。