我需要我的代码才能找到矩形的第四个顶点。试图做点什么,但总是失败。在某些情况下它可以工作,但不是每次都可以使用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
未指定每个顶点的输入顺序。
答案 0 :(得分:2)
如果有三个顶点,则矩形的一半:直角三角形。首先,您需要确定哪个点成直角。您可以通过不同的方式执行此操作。一种方法是应用毕达哥拉斯定理:找到相距最远的两个顶点。其余顶点成直角(另一种方法是计算每对边之间的点积,最接近零的边形成直角)。
让我们以直角A
以及其他两个B
和C
的角度调用顶点。现在,直角三角形的两个较短边的向量为B-A
和C-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。如果两点之间的长度小于此值,则可以将这两个点视为唯一点-它们保持在相同位置)。