poj 2194 Stacking Cylinders 计算几何之向量旋转

Stacking Cylinders
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 1069   Accepted: 571

Description

Cylinders (e.g. oil drums) (of radius 1 foot) are stacked in a rectangular bin. Each cylinder on an upper row rests on two cylinders in the row below. The cylinders in the bottom row rest on the floor. Each row has one less cylinder than the row below. 
poj 2194 Stacking Cylinders 计算几何之向量旋转_第1张图片

This problem is to write a program to compute the location of the center of the top cylinder from the centers of the cylinders on the bottom row. Computations of intermediate values should use double precision. 

Input

Each data set will appear in one line of the input. An input line consists of the number, n, of cylinders on the bottom row followed by n floating point values giving the x coordinates of the centers of the cylinders (the y coordinates are all 1.0 since the cylinders are resting on the floor (y = 0.0)). The value of n will be between 1 and 10 (inclusive). The end of input is signaled by a value of n = 0. The distance between adjacent centers will be at least 2.0 (so the cylinders do not overlap) but no more than 3.4 (cylinders at level k will never touch cylinders at level k – 2).

Output

The output for each data set is a line containing the x coordinate of the topmost cylinder rounded to 4 decimal places, a space and the y coordinate of the topmost cylinder to 4 decimal places. Note: To help you check your work, the x-coordinate of the center of the top cylinder should be the average of the x-coordinates of the leftmost and rightmost bottom cylinders.

Sample Input

4 1.0 4.4 7.8 11.2
1 1.0
6 1.0 3.0 5.0 7.0 9.0 11.0
10 1.0 3.0 5.0 7.0 9.0 11.0 13.0 15.0 17.0 20.4
5 1.0 4.4 7.8 14.6 11.2
0

Sample Output

6.1000 4.1607
1.0000 1.0000
6.0000 9.6603
10.7000 15.9100
7.8000 5.2143

Source

Pacific Northwest 2004

题目概述:一个箱子里一堆球,求最上面一个的坐标。

 

方法:给出两个球坐标,再计算出顶上第三个球的坐标。然后不断递推上去。


思路:二维数组存储每行每列圆的坐标,二维数组元素系自定义结构体类型包括横纵坐标。

      输入最底层坐标,即对数组 e[n][i] 赋值。并根据最底层圆的横坐标由小到大排序。

      两重循环由底向上求得上一层圆的坐标,即根据底层相邻的两个圆的坐标求出上一层位于这两个圆之间一个圆的坐标。



      具体求法:poj 2194 Stacking Cylinders 计算几何之向量旋转_第2张图片

             由于or 长度为半径的二倍,所以只需在线段 op 上截取 or 的长度 oq 使得 oq 绕 o 点旋转 一定角度便可求出 r 点坐标。 

             所以一要求q点坐标,二要求角rop。  求坐标时可用三角形相似。球角度可用(op/(2*or))的反余弦函数。


代码:

#include
#include
#include
#include
#define R 1.0


using namespace std;

int n;
int i,j;

struct E
{
    double x;
    double y;
};


E e[15][15];


E rotate(E o, double alpha, E p)
{
    E tmp;
    p.x-=o.x; p.y -= o.y;
    tmp.x = p.x * cos(alpha) - p.y * sin(alpha) +o.x;
    tmp.y = p.y * cos(alpha) + p.x * sin(alpha) +o.y;
    return tmp;
}


int cmp(E a,E b)
{
    return a.x }


int main()
{
    while(cin>>n &&  n)
    {
        for(i=0;i         {
            cin>>e[n][i].x;
            e[n][i].y=1.0;
        }
        sort(e[n],e[n]+n,cmp);
        for(i=n-1;i>=1;i--)
        {
            for(j=0;j             {


                double x1,x2,x3,y1,y2,y3,d;
                x1=e[i+1][j].x; y1=e[i+1][j].y;
                x2=e[i+1][j+1].x; y2=e[i+1][j+1].y;
                d=double(sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1)));
                x3=2.0*(x2-x1)/d+x1;
                y3=2.0*(y2-y1)/d+y1;
                double l=2.0*R;
                double o=acos(d/(l*2.0));
                E e1;
                e1.x=x3;
                e1.y=y3;
                e[i][j]=rotate(e[i+1][j],o,e1);
            }
        }
        printf("%.4f %.4f\n",e[1][0].x,e[1][0].y);
    }
    return 0;
}


你可能感兴趣的:(计算几何)