三维计算几何模板题,巧妙构造巧妙
一般情况是选一个对称轴,旋转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
input | output |
---|---|
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 |