zoukankan      html  css  js  c++  java
  • 向量旋转 UPC 2217

    这道题目是13山东省省赛的签到题,题目大意是给等边三角形的两个定点,让求逆时针旋转之后的第三个点的坐标,原来不会向量的旋转,在网上找了找,找到一篇挺好的,直接贴过来。

    向量的旋转

    实际做题中我们可能会遇到很多有关及计算几何的问题,其中有一类问题就是向量的旋转问题,下面我们来具体探讨一下有关旋转的问题。

    先我们先把问题简化一下,我们先研究一个点绕另一个点旋转一定角度的问题。已知A点坐标(x1,y1)B点坐标(x2,y2),我们需要求得A点绕着B点旋转θ度后的位置。

    如图:A' 就是A点绕B点旋转θ角度后得到的点,问题是我们要如何才能得到A' 点的坐标。(向逆时针方向旋转角度正,反之为负)研究一个点绕另一个点旋转的问题,我们可以先简化为一个点绕原点旋转的问题,这样比较方便我们的研究。之后我们可以将结论推广到一般的形式上。令B是原点,我们先以A点向逆时针旋转为例,我们过A' AB的垂线,交ABC,过Cx轴的平行线交过A' x轴的垂线于D。过点Cx轴的垂线交x轴于点E

    A的坐标(x,y)A' 坐标(x1,y1)B的坐标(0,0)。我们可以轻松的获取AB的长度,而且显而易见A' B长度等于AB。假设我们已知θ角的大小那么我们可以很快求出BCA' C的长度。BC=A' B x cosθA' C=A' B x sinθ

    因为∠A' CB和∠DCE为直角(显然的结论),则∠A' CD +DCB =ECD +DCB=90度。

    则∠A' CD=ECD,∠A' DC=CEB=90度,因此可以推断⊿CA' D ∽⊿CBE。由此可以退出的结论有:

    BC/BE=A' C/A' DBC/CE=A' C/CD

    当然了DCA' D都是未知量,需要我们求解,但是我们却可以通过求出C点坐标和E点坐标间接获得A' CCD的长度。我们应该利用相似的知识求解C点坐标。

    C点横坐标等于:((|AB| x cosθ) / |AB|) * x = x*cosθ

    C点纵坐标等于:((|AB| x cosθ) / |AB|) * y = y*cosθ

    CEBE的的长度都可以确定。

    我们可以通过相⊿CA' D ∽⊿CBE得出:

    AD = x * sinθ   DC = y * sinθ

    那么接下来很容易就可以得出:

    x1 = x*cosθ- y * sinθ y1 = y*cosθ + x * sinθ

    A' 的坐标为(x*cosθ- y * sinθ, y*cosθ + x * sinθ)

    我们可以这样认为:对于任意点A(x,y)A非原点,绕原点旋转θ角后点的坐标为:(x*cosθ- y * sinθ, y*cosθ + x * sinθ)

    接下来我们对这个结论进行一下简单的推广,对于任意两个不同的点AB(对于求点绕另一个点旋转后的坐标时,A B重合显然没有太大意义),求A点绕B点旋转θ角度后的坐标,我们都可以将B点看做原点,对AB进行平移变换,计算出的点坐标后,在其横纵坐标上分别加上原B点的横纵坐标,这个坐标就是A' 的坐标。

    推广结论:对于任意两个不同点ABAB旋转θ角度后的坐标为:

    (Δx*cosθ- Δy * sinθ+ xB, Δy*cosθ + Δx * sinθ+ yB )//结论

    注:xByBB点坐标。

    结论的进一步推广:对于任意非零向量AB(零向量研究意义不大),对于点C进行旋转,我们只需求出点AB对于点C旋转一定角度的坐标即可求出旋转后的向量A' B' ,因为向量旋转后仍然是一条有向线段。同理,对于任意二维平面上的多边形旋转也是如此。

    以上是比较简单的,最后把结论记好就行了。上面是绕B点进行旋转的,所以Δx = xa - xb, Δy = ya - yb,如果绕A反过来就行了。

    题目代码:

    /*************************************************************************
        > File Name:            upc_2217.cpp
        > Author:               Howe_Young
        > Mail:                 1013410795@qq.com
        > Created Time:         2015年04月29日 星期三 20时03分21秒
     ************************************************************************/
    
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    #include <algorithm>
    
    using namespace std;
    
    int main()
    {
        int t;
        double x1, y1, x2, y2;
        scanf("%d", &t);
        while (t--)
        {
            scanf("%lf %lf %lf %lf", &x1,  &y1, &x2, &y2);
            double x3, y3;
            x3 = (x2 - x1) * 0.5 - (y2 - y1) * sqrt(3.0) / 2.0 + x1;
            y3 = (y2 - y1) * 0.5 + (x2 - x1) * sqrt(3.0) / 2.0 + y1;
            printf("(%.2f,%.2f)
    ", x3, y3);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    How to build Linux system from kernel to UI layer
    Writing USB driver for Android
    Xposed Framework for Android 8.x Oreo is released (in beta)
    Linux Smartphone Operating Systems You Can Install Today
    Librem 5 Leads New Wave of Open Source Mobile Linux Contenders
    GUADEC: porting GNOME to Android
    Librem 5 – A Security and Privacy Focused Phone
    GNOME and KDE Join Librem 5 Linux Smartphone Party
    Purism计划推出安全开源的Linux Librem 5智能手机
    国产系统之殇:你知道的这些系统都是国外的
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4466975.html
Copyright © 2011-2022 走看看