• HDU 4998 (点的旋转) Rotate


    为了寻找等效旋转操作,我们任选两个点P0和Q0,分别绕这n个点旋转一定的角度后最终得到Pn和Qn

    然后已知:P0和Pn共圆,Q0和Qn共圆。所以要找的等效旋转点就是这两个线段的垂直平分线交点O。

    等效的角度的计算,可以利用已知的等腰三角形(这里有两个)△P0PnR,做一条垂线(三线合一的性质),再利用反三角函数计算半角,再乘二

    还有一种特殊情况就是,如果答案比平角要大,我们计算的角度就不对了。

    此时可以让P0逆时针旋转90°得到一个P1,然后将P1和Pn的坐标分别代入直线P0R的方程,如果异号,说明P1和Pn在直线两侧;同号说明同侧。

    也就是异侧的话,就要将所求角度用2π减去它。

     1 //#define LOCAL
     2 #include <iostream>
     3 #include <cstdio>
     4 #include <cstring>
     5 #include <cmath>
     6 using namespace std;
     7 
     8 void Rote(double& a1, double& b1, double a2, double b2, double p)
     9 {
    10     double tempx = a1, tempy = b1;
    11     tempx = cos(p)*(a1 - a2) + sin(p)*(b2 - b1) + a2;    
    12     tempy = sin(p)*(a1 - a2) + cos(p)*(b1 - b2) + b2;
    13     a1 = tempx;
    14     b1 = tempy;
    15 }
    16 
    17 double dis(double a1, double b1, double a2, double b2)
    18 {
    19     return sqrt((a1-a2)*(a1-a2) + (b1-b2)*(b1-b2));
    20 }
    21 
    22 int main(void)
    23 {
    24     #ifdef LOCAL
    25         freopen("Bin.txt", "r", stdin);
    26     #endif
    27 
    28     int T;
    29     scanf("%d", &T);
    30     while(T--)
    31     {
    32         int n;
    33         scanf("%d", &n);
    34         double P0x = 0.123, P0y = 0.312, Q0x = 1.589, Q0y = 1.455;
    35         double Pnx = P0x, Pny = P0y, Qnx = Q0x, Qny = Q0y;
    36         for(int i = 0; i < n; ++i)
    37         {
    38             double P1x, P1y, alpha;
    39             scanf("%lf%lf%lf", &P1x, &P1y, &alpha);
    40             Rote(Pnx, Pny, P1x, P1y, alpha);
    41             Rote(Qnx, Qny, P1x, P1y, alpha);
    42         }
    43         double A1 = P0x - Pnx, B1 = P0y - Pny, C1 = (P0x*P0x + P0y*P0y - Pnx*Pnx - Pny*Pny) / 2;
    44         double A2 = Q0x - Qnx, B2 = Q0y - Qny, C2 = (Q0x*Q0x + Q0y*Q0y - Qnx*Qnx - Qny*Qny) / 2;
    45         double ansx = (C1*B2 - C2*B1) / (A1*B2 - A2*B1);
    46         double ansy = (C1*A2 - C2*A1) / (B1*A2 - B2*A1);
    47 
    48         double zx = (P0x + Pnx) / 2, zy = (P0y + Pny) / 2;
    49         double ansa = acos(dis(zx,zy, ansx, ansy) / dis(P0x, P0y, ansx, ansy)) * 2;
    50 
    51         double P1x = ansx - (P0y - ansy), P1y = ansy + (P0x - ansx);
    52         if(((P0y-ansy)*(P1x-ansx)-(P0x-ansx)*(P1y-ansy)) * ((P0y-ansy)*(Pnx-ansx)-(P0x-ansx)*(Pny-ansy)) < 0)
    53             ansa = 3.1415926536 * 2 - ansa;
    54 
    55         printf("%.10lf %.10lf %.10lf
    ", ansx, ansy, ansa);
    56     }
    57     return 0;
    58 }
    代码君

    还有一种复数的方法,<complex>里面已经有了现成的复数数据类型和函数了,用起来很方便。

    这是上交一队的代码,膜拜了

     1 #include <cstdlib>
     2 #include <cctype>
     3 #include <cstring>
     4 #include <cstdio>
     5 #include <cmath>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <string>
     9 #include <iostream>
    10 #include <sstream>
    11 #include <map>
    12 #include <set>
    13 #include <queue>
    14 #include <stack>
    15 #include <fstream>
    16 #include <numeric>
    17 #include <iomanip>
    18 #include <bitset>
    19 #include <list>
    20 #include <stdexcept>
    21 #include <functional>
    22 #include <utility>
    23 #include <ctime>
    24 #include <cassert>
    25 #include <complex>
    26 using namespace std;
    27 #define rep(i,a,n) for (int i=a;i<n;i++)
    28 #define per(i,a,n) for (int i=n-1;i>=a;i--)
    29 #define pb push_back
    30 #define mp make_pair
    31 #define all(x) (x).begin(),(x).end()
    32 #define fi first
    33 #define se second
    34 #define SZ(x) ((int)(x).size())
    35 #define ACCU accumulate
    36 #define TWO(x) (1<<(x))
    37 #define TWOL(x) (1ll<<(x))
    38 #define clr(a) memset(a,0,sizeof(a))
    39 #define POSIN(x,y) (0<=(x)&&(x)<n&&0<=(y)&&(y)<m)
    40 #define PRINTC(x) cout<<"Case #"<<++__<<": "<<x<<endl
    41 #define POP(x) (__builtin_popcount(x))
    42 #define POPL(x) (__builtin_popcountll(x))
    43 typedef vector<int> VI;
    44 typedef vector<string> VS;
    45 typedef vector<double> VD;
    46 typedef long long ll;
    47 typedef long double LD;
    48 typedef pair<int,int> PII;
    49 typedef pair<ll,ll> PLL;
    50 typedef vector<ll> VL;
    51 typedef vector<PII> VPII;
    52 typedef complex<double> CD;
    53 const int inf=0x20202020;
    54 const ll mod=1000000007;
    55 const double eps=1e-9;
    56 const double pi=3.1415926535897932384626;
    57 const int DX[]={1,0,-1,0},DY[]={0,1,0,-1};
    58 ll powmod(ll a,ll b) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    59 ll powmod(ll a,ll b,ll mod) {ll res=1;a%=mod;for(;b;b>>=1){if(b&1)res=res*a%mod;a=a*a%mod;}return res;}
    60 ll gcd(ll a,ll b) { return b?gcd(b,a%b):a;}
    61 // head
    62 
    63 int _,n;
    64 CD k,b,p;
    65 double x,y,c;
    66 int main() {
    67     for (scanf("%d",&_);_;_--) {
    68         k=CD(1,0);b=CD(0,0);
    69         scanf("%d",&n);
    70         rep(i,0,n) {
    71             scanf("%lf%lf%lf",&x,&y,&c);
    72             p=CD(x,y);
    73             k=k*CD(cos(c),sin(c));
    74             b=(b-p)*CD(cos(c),sin(c))+p;
    75         }
    76         double the=arg(k);
    77         while (the<0) the+=2*pi;
    78         while (the>=2*pi) the-=2*pi;
    79         p=b/(CD(1,0)-k);
    80         printf("%.10f %.10f %.10f
    ",real(p),imag(p),the);
    81     }
    82 }
    外来的代码君
  • 相关阅读:
    实时控制软件设计第一周作业-汽车ABS软件系统案例分析
    团队项目·冰球模拟器——任务间通信、数据共享等设计
    团队项目·冰球模拟器——cmake 自动化构建系统的配置文件的编写
    团队项目·冰球模拟器——文件结构设计
    团队项目·冰球模拟器——插值算法接口设计
    第四周作业
    第三周作业、实时操作系统µC/OS介绍及其它内容
    第二周作业、停车场门禁控制系统状态机
    Open Dynamics Engine for Linux 安装笔记
    第一周作业、典型实时控制系统案例分析
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/3970438.html
Copyright © 2020-2023  润新知