查找矩形的第四个顶点

时间:2018-11-19 22:47:05

标签: c++

我需要我的代码才能找到矩形的第四个顶点。试图做点什么,但总是失败。在某些情况下它可以工作,但不是每次都可以使用bot。有人可以帮我吗? 同样,它必须使用2个类来完成,一个类用于顶点,另一类用于整个矩形。 问题是我的代码适用于特定的顶点设置。我尝试了很多事情,但仍然失败。

代码如下:

#include <iostream>
#include <cmath>
using namespace std;

class vertex{
    public: 
        double x;
        double y;
        void insert(){
            cin>>x;
            cin>>y;
        }
};

class rect{
    private:
        double ax, ay, bx, by, cx, cy, dx, dy;
    public:
        void insert_data(vertex A, vertex B, vertex C){         //inserting rectangle data
            ax=A.x;
            ay=A.y;
            bx=B.x;
            by=B.y;
            cx=C.x;
            cy=C.y;
        }
        void calculate(){           //finding 4h vertex coordinates
        dx=cx+(abs(ax-bx));
        dy=cy+(abs(ay+by));
        }       
        void out(){                 //output
            cout<<dx<<" "<<dy;
        }

};





using namespace std;

int main() {
    vertex A, B, C;
    A.insert();
    B.insert();
    C.insert();
    rect X;
    X.insert_data(A, B, C);
    X.calculate();
    X.out();


    return 0;
}

正如我现在考虑的那样,它可能与将坐标插入正确的变量有关,但是无法想到解决此问题的解决方案。

例如:
输入:
1 1
0 3
3 2
输出:
2 4

未指定每个顶点的输入顺序。

2 个答案:

答案 0 :(得分:2)

如果有三个顶点,则矩形的一半:直角三角形。首先,您需要确定哪个点成直角。您可以通过不同的方式执行此操作。一种方法是应用毕达哥拉斯定理:找到相距最远的两个顶点。其余顶点成直角(另一种方法是计算每对边之间的点积,最接近零的边形成直角)。

让我们以直角A以及其他两个BC的角度调用顶点。现在,直角三角形的两个较短边的向量为B-AC-A。如果将这些边添加到A,将得到第四个顶点:

D=A+(B-A)-(C-A)=B+C-A

答案 1 :(得分:1)

使用向量是一个非常有趣的主题。以下是有关vector

的一些很好的解释

要回答您的问题:

在3个给定的顶点A,B和C中,只有三种直角情况:在A,B或C。如果找到了直角,例如,在B(无论A的顺序如何)和C),则可以通过以下公式计算出D坐标:D = A + C-B。

要检测直角是否在B:两个向量BA和BC的点积均为0,无论A和C的顺序如何。

以C ++方式(不是C方式),您应该在顶点类中添加运算符来操纵矢量,这是一个示例:

#define MY_EPSILON 10E-6

class vertex {
public:
        double X, Y;
        vertex(double x_, double y_ ) :X(x_), Y( y_){}
        vertex():X(0), Y(0){}

        vertex operator +( vertex v ){ return vertex( X + v.X, Y + v.Y ); }
        vertex operator -( vertex v ){ return vertex( X - v.X, Y - v.Y ); }
        double dot( vertex v ){ return X * v.X + Y * v.Y; }
        double length() { return sqrt(X * X + Y * Y ); }
        vertex normalize( bool &bOk ){
                double len = length(); bOk = false; 
                if( len > MY_EPSILON ){  bOk = true; return vertex( X/len, Y/len ); }
                return *this;
        }       
};

std::ostream & operator << ( std::ostream & s, vertex v ){
        s << std::setprecision(6) << "(" << v.X << "," << v.Y << ") ";
        return s;
}

两个向量的点积:

要验证直角是否在B点处,我们可以使用以下函数,它将计算AB和BC的两个归一化向量的点积:

bool isRighAngle( vertex a, vertex b, vertex c){
     bool bOkAB, bOkBC;
     vertex uAB = ( b - a ).normalize( bOkAB ), uBC = ( c - b ).normalize( bOkBC );
     return bOkAB && bOkBC && fabs(uAB.dot( uBC )) < MY_EPSILON;
}

请注意,当我们对一个零的double值进行补偿时,请始终使用epsilon,对于double而言,绝对值不为零。如果无法计算归一化向量之一(两个点彼此之间太近),则此函数还会返回false。

从直角计算最后一个坐标:

如果从直角B计算最后一个坐标D,则以下函数返回true:

    bool getLastCoordinateIfRightAngle( vertex a, vertex b, vertex c, vertex & d ){
            if( isRighAngle( a, b, c ) ){
                    d = (a + c) - b;
                    return true;
            }
            return false;
    }

寻找直角:

因此,要从3个顶点A,B和C中找到最后一个坐标D,应该对三种直角情况进行测试,找到解后测试将停止:

    bool getLastCoordinate( vertex a, vertex b, vertex c, vertex &d ){

            if( getLastCoordinateIfRightAngle( a, b, c, d )   //if B is at the right angle
                || getLastCoordinateIfRightAngle( a, c, b, d ) //if C is at the right angle
                || getLastCoordinateIfRightAngle( b, a, c, d ) ) //if A is at the right angle
            {
                    return true;
            }

            //No right angle found.
            return false;
    }       

快速测试:

我们可以对其进行快速测试:

    int main(int argc, char *argv[])
    {
        vertex A(0.0, 0.0), B(1.0, 0.0), C(0.0, 1.0), D;

        if( getLastCoordinate( A, B, C, D ) ){
            std::cout << "D coordinate " << D << " found from inputs :  " << A << B << C << std::endl;
        }else {
            std::cout << "D coordinate not found for input:  " << A << B << C << std::endl;
        }

        return 0;
    }

EPSILON CHOICE:

这取决于您的域,如果您在一个很小的对象域中工作(X,Y)非常小(例如,接近10E-5),则计算会遇到一些困难(GPU中的浮点为精度非常有限)。最好将工作域转换为正常范围。 在上面的示例中,EPSILON设置为10E-6。如果两点之间的长度小于此值,则可以将这两个点视为唯一点-它们保持在相同位置)。