URAL2050 3D-modeling 计算几何

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

一般情况是选一个对称轴,旋转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

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 points A and B. These points lie on the drawn line. The third and the fourth lines contain coordinates of the points C and D. These points lie on the line Vasya was going to draw. Point A doesn’t coincide with point B, point C doesn’t coincide with point D. 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 points P and Q which lie on the rotation axis. In the third line output the rotation angle α in degrees. The distance between points P and Q should not be less than 1. The coordinates of points P and Q should not exceed 2000 by absolute value. The angle should lie within the range [0; 360] and be counted counterclockwise, if one is looking from P to the direction of Q. An answer is considered correct if after rotation of the line CD by the angle α around the axis PQ it results in some line EF, such that the distances from points A and B to this line EF don’t exceed 10 −5.

Sample Input

inputoutput
0 0 0
0 1 0
0 0 0
1 0 0
0 0 1
0 0 0
90
1 0 1
1 0 0
0 1 1
0 1 0
0 0 1
0 0 0
270



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值