Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <cmath>
- #include <vector>
- #include <assert.h>
- const double pi = 3.141592653589793238462643;
- const double accuracy = 0.0000001;
- class Vector {
- public:
- double x;
- double y;
- double z;
- Vector() = default;
- Vector(double x,double y, double z) : x(x), y(y), z(z){}
- Vector(const Vector& vector) = default;
- friend bool operator == (const Vector& left, const Vector& right);
- friend bool operator != (const Vector& left, const Vector& right);
- friend Vector operator + (const Vector& left, const Vector& right);
- friend bool operator < (const Vector& left, const Vector& right);
- friend bool operator > (const Vector& left, const Vector& right);
- friend bool operator >= (const Vector& left, const Vector& right);
- friend bool operator <= (const Vector& left, const Vector& right);
- friend Vector operator - (const Vector& left, const Vector& right);
- friend Vector operator / (const Vector& left, const double& right);
- void operator += (const Vector& other){
- x += other.x;
- y += other.y;
- z += other.z;
- }
- void operator -= (const Vector& other){
- x -= other.x;
- y -= other.y;
- z -= other.z;
- }
- void operator /= (const double& c){
- assert(c >0);
- x /= c;
- y /= c;
- z /= c;
- }
- void operator *= (const double& c) {
- x *= c;
- y *= c;
- z *= c;
- }
- };
- /*
- * Арифметические операции
- */
- Vector operator + (const Vector& left, const Vector& right){
- Vector data = left;
- data += right;
- return data;
- }
- Vector operator - (const Vector& left, const Vector& right){
- Vector data = left;
- data -= right;
- return data;
- }
- Vector operator / (const Vector& left, const double& right){
- assert(right != 0);
- Vector data = left;
- data /= right;
- return data;
- }
- Vector operator * (const Vector& left, const double right){
- Vector data = left;
- data *= right;
- return data;
- }
- /*
- * Операции сравнения
- */
- bool operator > (const Vector& left, const Vector& right) {
- return (left.x>right.x) && (left.y > right.y) && (left.z > right.z);
- }
- bool operator < (const Vector& left, const Vector& right) {
- return (left.x<right.x) && (left.y < right.y) && (left.z < right.z);
- }
- bool operator <= (const Vector& left, const Vector& right) {
- return (left.x<=right.x) && (left.y <= right.y) && (left.z <= right.z);
- }
- bool operator >= (const Vector& left, const Vector& right) {
- return (left.x>=right.x) && (left.y >= right.y) && (left.z >= right.z);
- }
- bool operator == (const Vector& left, const Vector& right) {
- return fabs(left.x - right.x) < accuracy && fabs(left.y - right.y) < accuracy;
- }
- bool operator != (const Vector& left, const Vector& right) {
- return !(left == right);
- }
- double scalarMul (const Vector& first, const Vector& second) {
- return first.x * second.x + first.y * second.y + first.z * second.z;
- }
- Vector vectorMul (const Vector& first, const Vector& second) {
- return Vector(first.y*second.z - first.z*second.y,
- first.z*second.x - first.x*second.z,
- first.x*second.y - first.y*second.x);
- }
- double distance (const Vector& first, const Vector& second) {
- return sqrt( 256 *((first.x-second.x)*(first.x-second.x)
- + (first.y-second.y)*(first.y-second.y) +
- (first.z-second.z)*(first.z-second.z)))/16;
- }
- class Plane {
- public:
- Vector normal;
- double D;
- Plane (const Vector& firstP, const Vector& secondP, const Vector& thirdP) {
- Vector firstV = firstP - thirdP, secondV = secondP - thirdP;
- normal = vectorMul(firstV, secondV);
- D = - scalarMul(normal, thirdP);
- }
- };
- double distance(Vector& point, Plane& plane) {
- assert(plane.normal!= Vector(0,0,0));
- return fabs(scalarMul(plane.normal, point) + plane.D)/distance(plane.normal, Vector(0, 0, 0));
- }
- Vector proection(Vector& point, Plane& plane) {
- return point - plane.normal*(scalarMul(point, plane.normal) + plane.D)/scalarMul(plane.normal, plane.normal);
- }
- class Segment{
- public:
- Vector firstP;
- Vector secondP;
- Segment(Vector& firstP, Vector& secondP) : firstP(firstP), secondP(secondP) {
- }
- };
- bool isSameSign(double x, double y) {
- return (x >= 0 && y >= 0) || (x <= 0 && y <= 0);
- }
- bool Intersect(Segment& first, Segment& second) {
- Vector segment = first.firstP - first.secondP;
- Vector fTriangle = second.firstP - first.secondP;
- Vector sTriangle = second.secondP - first.secondP;
- Vector firstNormal = vectorMul(segment, fTriangle);
- Vector secondNormal = vectorMul(segment, sTriangle);
- if (firstNormal != Vector(0,0,0) && secondNormal != Vector(0,0,0)) {
- return !isSameSign(firstNormal.x, secondNormal.x) ||
- !isSameSign(firstNormal.y, secondNormal.y) ||
- !isSameSign(firstNormal.z, secondNormal.z);
- } else {
- if (firstNormal == Vector(0,0,0) && (second.firstP <= first.firstP&& second.firstP >= first.secondP||
- second.firstP >= first.firstP&& second.firstP <= first.secondP)) {
- return true;
- }
- if (secondNormal == Vector(0,0,0) && (second.secondP <= first.firstP&& second.secondP >= first.secondP||
- second.secondP >= first.firstP&& second.secondP <= first.secondP)) {
- return true;
- }
- if (firstNormal == Vector(0,0,0) && secondNormal == Vector(0,0,0)
- && (first.firstP <= second.firstP && first.firstP >= second.secondP||
- first.firstP >= second.firstP && first.firstP <= second.secondP)) {
- return true;
- }
- return false;
- }
- }
- int main() {
- int x, y, z;
- std::cout.precision(7);
- std::vector<Vector> points (4) ;
- for (int i = 0; i < 4; i++) {
- std::cin >> x >> y >> z;
- points[i] = Vector(x, y, z);
- }
- /*if (points[0] == points[1] && points[2] == points[3]) {
- std::cout << distance(points[0], points[2]);
- } else{*/
- if (vectorMul(points[1] - points[0], points[3]- points[2]) == Vector(0, 0, 0)) {
- Vector normal = vectorMul(vectorMul(points[1] - points[0], points[2] - points[0]), points[1] - points[0])
- /scalarMul(points[1] - points[0], points[1] - points[0]);
- Vector d = normal + points[0], e = normal + points[1];
- Segment a(points[2], points[3]), b(d, e);
- if (Intersect(a, b)) {
- std::cout <<fabs(distance(vectorMul(points[1] - points[0], points[2] - points[0]),
- Vector(0,0,0)))/distance(points[1] - points[0], Vector(0,0,0));
- } else {
- std::cout << std::min(std::min(distance(points[0], points[3]), distance(points[1], points[3])),
- std::min(distance(points[0], points[2]), distance(points[1], points[2])));
- std::cout << std::endl;
- }
- } else {
- Plane c(points[0], points[1], points[0] + points[2] - points[3]);
- Segment a(points[0], points[1]);
- Vector d = proection(points[2], c), e = proection(points[3], c);
- Segment b(d, e);
- if (Intersect(a, b)) {
- std::cout << distance(points[3], c);
- } else {
- std::cout << std::min(std::min(distance(points[0], points[3]), distance(points[1], points[3])),
- std::min(distance(points[0], points[2]), distance(points[1], points[2])));
- std::cout << std::endl;
- }
- }
- return 0;
- }
Add Comment
Please, Sign In to add comment