URAL2050 3D-modeling 计算几何

来源:互联网 发布:band of brothers 知乎 编辑:程序博客网 时间:2024/05/19 08:01

三维计算几何模板题,巧妙构造巧妙

一般情况是选一个对称轴,旋转180度即可

具体分三类:

1.两直线平行时,两直线中间的直线,旋转180度

2.两直线重合,直接输出第一条直线,旋转0度

3.其他情况,就是异面直线和相交的情况,找一条直线L与两直线垂直且相交(即法向量的修正版),过L的中点做两直线的角平分线(跟两直线平移相交后的角平分线差不多)即为所求,旋转180度


另外,通过求等腰三角形的中线,就是角平分线(三角形性质)(两个直线的方向向量单位化)


感谢@FZ

/* * Author: NICK WONG * Created Time:  2015/8/25 20:34:59 * File Name: e.cpp */#include<iostream>#include<sstream>#include<fstream>#include<vector>#include<list>#include<deque>#include<queue>#include<stack>#include<map>#include<set>#include<bitset>#include<algorithm>#include<cstdio>#include<cstdlib>#include<cstring>#include<cctype>#include<cmath>#include<ctime>#include<iomanip>using namespace std;const double eps(1e-8);const int maxn=10100;const long long maxint=-1u>>1;const long long maxlong=maxint*maxint;typedef long long lint;struct Point {    double x , y , z;    Point(){}    Point(double x,double y,double z):x(x),y(y),z(z){}    void in() {        scanf("%lf%lf%lf",&x,&y,&z);    }    void out() {        printf("%.9f %.9f %.9f\n",x,y,z);    }};Point operator - ( Point a , Point b ) {    return Point ( a.x - b.x , a.y - b.y , a.z - b.z );}Point operator + ( Point a , Point b ) {    return Point ( a.x + b.x , a.y + b.y , a.z + b.z );}Point operator * ( Point a , double d ) {    return Point ( a.x * d , a.y * d , a.z * d );}Point operator / ( Point a , double d ) {    return Point ( a.x / d , a.y / d , a.z / d );}double dot ( Point a , Point b ) {    return a.x * b.x + a.y * b.y + a.z * b.z;}Point det ( Point a , Point b ) {    return Point ( a.y*b.z - a.z*b.y , a.z*b.x - a.x*b.z , a.x*b.y-a.y*b.x );}struct Line {    Point a , b;    Line(){}    Line( Point a , Point b ) : a(a) , b(b) {}};struct Plane {    Point a , b , c;    Plane(){}    Plane(Point a,Point b,Point c):a(a),b(b),c(c){}};Point pvec ( Plane s ) { //fa    return det ( s.a - s.b , s.a - s.c );}Point intersection ( Line l , Plane s ) {    Point ret = pvec(s);    double t = ( ret.x*(s.a.x-l.a.x) + ret.y*(s.a.y-l.a.y) + ret.z*(s.a.z-l.a.z) ) /               ( ret.x*(l.b.x-l.a.x) + ret.y*(l.b.y-l.a.y) + ret.z*(l.b.z-l.a.z) ) ;    ret = l.a + ( l.b - l.a ) * t;    return ret;}double len ( Point a ) {    return sqrt( dot(a,a) );}int parallel ( Line u , Line v ) {    return len ( det ( u.a - u.b , v.a - v.b ) ) < eps;}Point a,b,c,d;void init(){}void work(){    a.in(); b.in(); c.in(); d.in();    Line l1 = Line(a,b);    Line l2 = Line(c,d);        if (parallel(l1,l2))//平行    {        Plane p = Plane(a,b,c);        Point v = pvec(p);        if (len(v)<eps) //points in line 法向量为0,三点共线        {            a.out();            b = b+(a-b)/len(a-b)*10.0;            b.out();            puts("0");            return;        }        Point mid1 = (a+c)/2.0;        Point mid2 = (a+d)/2.0;        Point v2 = mid1+(mid2-mid1)/len(mid2-mid1)*10.0;        mid1.out();        v2.out();        puts("180");        return;       }        Point v = det(a-b, c-d); //法向量    Plane pl1 = Plane(a,b,a+v);    Plane pl2 = Plane(c,d,c+v);    Point p1 = intersection(l1,pl2); //l1的交点    Point p2 = intersection(l2,pl1); //l2的交点        Point mid = (p1+p2)/2.0; //中点    Point t1 = mid+(a-b)/len(a-b);    Point t2 = mid+(c-d)/len(c-d);    Point mid2 = (t1+t2)/2.0;    mid2 = mid+(mid2-mid)/len(mid2-mid)*10.0; 求角平分线    mid.out();    mid2.out();    puts("180");}int main(){       init();    work();    return 0;}
E - 3D-modeling

Crawling in process...Crawling failedTime Limit:1000MS    Memory Limit:65536KB    64bit IO Format:%I64d & %I64u

SubmitStatusPractice URAL 2050

Description

Android Vasya’s elder friends have already been modeling six-dimensional space ships for quite a long time. Vasya himself hasn’t yet acquired such level of mastering. He has only just started the 3d-modeling course. And right now he is doing his first homework.
The homework is pretty easy, one just needs to make a 3d-drawing of any detail. Vasya has already come up with the detail he wants to draw, imagined how it would look like and he even has drawn the first straight line. But something went wrong. Apparently the line turned out to be not the one he needed.
But Vasya has already got the solution for this problem. He plans to rotate the detail in his mind in such a way, that the line he was going to draw would become the line he had actually drawn. Help Vasya find out what rotation he should make for this.

Input

First two lines contain coordinates of the pointsA andB. These points lie on the drawn line. The third and the fourth lines contain coordinates of the pointsC andD. These points lie on the line Vasya was going to draw. PointA doesn’t coincide with pointB, point C doesn’t coincide with pointD. All numbers in the input data are integers and do not exceed 1000 by absolute value.

Output

If the required rotation doesn’t exist output “Impossible” in a single line. Otherwise in the first two lines output coordinates of the pointsP andQ which lie on the rotation axis. In the third line output the rotation angleα in degrees. The distance between pointsP and Q should not be less than 1. The coordinates of pointsP andQ should not exceed 2000 by absolute value. The angle should lie within the range [0; 360] and be counted counterclockwise, if one is looking fromP to the direction ofQ. An answer is considered correct if after rotation of the lineCD by the angleα around the axis PQ it results in some lineEF, such that the distances from pointsA and B to this lineEF don’t exceed 10 −5.

Sample Input

inputoutput
0 0 00 1 00 0 01 0 0
0 0 10 0 090
1 0 11 0 00 1 10 1 0
0 0 10 0 0270



0 0
原创粉丝点击