• 向量旋转 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
  • 相关阅读:
    effective C++ 条款 46:需要类型转换时请为模板定义非成员函数
    effective C++ 条款 42:了解typename的双重意义
    effective C++ 条款 38:通过复合塑模出hasa或“根据某物实现出”
    effective C++ 条款 44:将与参数无关的代码抽离templates
    职场女性工作的六大禁忌
    正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码,这样做会导致应用程序挂起
    C# 截图 窗体截图 屏幕截图
    C# 创建DataSet 实例
    c# WinForm 中鼠标控制窗体的移动
    访问用户控件里面的控件的两种方法
  • 原文地址:https://www.cnblogs.com/Howe-Young/p/4466975.html
Copyright © 2020-2023  润新知