Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 给定矩形的一边,计算其他一边_C++_Geometry - Fatal编程技术网

C++ 给定矩形的一边,计算其他一边

C++ 给定矩形的一边,计算其他一边,c++,geometry,C++,Geometry,我正在努力解决一个我认为应该很容易解决的问题: 我得到了两个点x1,x2和一个宽度值。如何计算与x1和x2平行的另外两个点,使其形成一个矩形 我试着从这里和这里找到答案。尽管这两种解决方案都失败了 背景:这是关于将图像投影到真实世界坐标中。因此,我需要找到与我提供的直线平行的直线,以便两条直线的点创建一个矩形。我不想自己应用旋转 以下是我想要实现的目标: 在这个示例中,您可以看到x1、x2和我提供的宽度。我在找x3和x4,这样点就形成了一个矩形 如果可能的话,我正在寻找C++实现。 下面是

我正在努力解决一个我认为应该很容易解决的问题:

我得到了两个点x1,x2和一个宽度值。如何计算与x1和x2平行的另外两个点,使其形成一个矩形

我试着从这里和这里找到答案。尽管这两种解决方案都失败了

背景:这是关于将图像投影到真实世界坐标中。因此,我需要找到与我提供的直线平行的直线,以便两条直线的点创建一个矩形。我不想自己应用旋转

以下是我想要实现的目标:

在这个示例中,您可以看到x1、x2和我提供的宽度。我在找x3和x4,这样点就形成了一个矩形

如果可能的话,我正在寻找C++实现。

下面是我实现的代码。正如你们所看到的,我使用的是提供给我的右上角和左上角坐标。但我宁愿找到一条与提供的点平行的线:

   double distance = 77.5;//[self normalizedDistanceWithCRS:crs p1:topLeft p2:topRight];

    // calculate the rotated coordinates for bottom right and bottom left with provided height
    double angle = atan2(sinuTL.y - sinuTR.y, sinuTL.x - sinuTR.x); //  * 180 / M_PI

    double x = distance;
    double y = height;
    double xBRTrans = x*cos(angle) - y*sin(angle);
    xBRTrans = sinuTL.x - xBRTrans;
    double yBRTrans = x*sin(angle) + y*cos(angle);
    yBRTrans = sinuTL.y - yBRTrans;

    x = 0;
    y = height;
    double xBLTrans = x*cos(angle) - y*sin(angle);
    xBLTrans += sinuTL.x;
    double yBLTrans = x*sin(angle) + y*cos(angle);
    yBLTrans = sinuTL.y - yBLTrans;
**更新**

我已经修改了下面提供的解决方案中的代码,结果仍然不是我所期望的。给出了左侧的两点,计算了右侧的两点。你可以看到有一个偏移(点应该在建筑物的拐角处,也忽略了中间的蓝色点,这对这个问题毫无意义):

守则:

double height = 57;
// get coords from provided input
double x1x=629434.24373957072, x1y=5476196.7595944777, x2x=629443.08914538298, x2y=5476120.1852802411;
// x2x3 = Vector from point x2 to point x3, assume x value as 1
double x2x3x = 1;
// calculate y-value, using the fact that dot-product of orthogonal vectors is 0
double x2x3y = x2x*x2x3x / (-1 * x2y);
// calculate length of vector x2x3
double length_e_vec_x2_x3 = sqrt(pow(x2x3x,2) + pow(x2x3y,2));
// stretch vector to provided witdh
x2x3x = x2x3x*height / length_e_vec_x2_x3;
x2x3y = x2x3y*height / length_e_vec_x2_x3;
// since x2x3 and x1x4 are equal, simple addition remains
double x3x, x3y, x4x, x4y;
x3x = x2x + x2x3x;
x3y = x2y + x2x3y;
x4x = x1x + x2x3x;
x4y = x1y + x2x3y;
更新

事实上,所有的答案和我自己的代码都能正常工作。不幸的是,我被蒙上了眼睛,没有注意到这个问题是由于该地区使用了不适当的地理投影。因此坐标来自WGS84 long/lat,在计算完成之前,将其转换为正弦投影,然后再转换回WGS84。正弦投影保留区域(等面积投影),但会扭曲区域内的形状。你不能只加上一些米,然后再转换回来。我应该早一点意识到这一点,而且我看错了地方


我将选择最详尽的答案作为“获胜者”。尽管经过测试,我可以说所有提供的解决方案实际上都是有效的

一般建议:

X1: 629434/5.4762e+06
X2: 629443/5.47612e+06
X3: 629500/5.47613e+06
X4: 629491/5.4762e+06
如果我是你,我会为向量构建类,并为所需的操作构建函数,然而这个例子应该做你想做的

矢量、绝对坐标和相对坐标:

X1: 629434/5.4762e+06
X2: 629443/5.47612e+06
X3: 629500/5.47613e+06
X4: 629491/5.4762e+06
重要提示:您正在使用坐标,这是一种非常简单的方法。如果向您提供解决方案的人员将给定点设置为0/0,即原点,则您不能仅更改此设置。我更改了下面的代码,以适应您对提供的输入所做的更改

double width = 35;

// get coords from provided input
double x1x=0, x1y=0, x2x=x, x2y=y;
// x2x3 = Vector from point x2 to point x3, assume x value as 1
double x2x3x = 1;
// calculate y-value, using the fact that dot-product of orthogonal vectors is 0
double x2x3y = x2x*x2x3x / (-1 * x2y);
// calculate length of vector x2x3
double length_e_vec_x2_x3 = sqrt(pow(x2x3x,2) + pow(x2x3y,2));
// stretch vector to provided witdh
x2x3x = x2x3x*width / length_e_vec_x2_x3;
x2x3y = x2x3y*width / length_e_vec_x2_x3;
// since x2x3 and x1x4 are equal, simple addition remains
double x3x, x3y, x4x, x4y;
x3x = x2x + x2x3x;
x3y = x2y + x2x3y;
x4x = x1x + x2x3x;
x4y = x1y + x2x3y;

// check results
cout << "X1: " << x1x << "/" << x1y << endl;
cout << "X2: " << x2x << "/" << x2y << endl;
cout << "X3: " << x3x << "/" << x3y << endl;
cout << "X4: " << x4x << "/" << x4y << endl;
验证

Dotproduct should be 0: 5.68434e-14
如本代码注释所述,如果两个向量相互正交,则两个向量的点积将返回0。通过使用它,可以验证提供的结果。 添加少量代码以验证结果:

// verify results
cout << "Dotproduct should be 0: " << (x2x*x2x3x)+(x2y*x2x3y) << endl;
它打印0,因此代码正在执行它应该执行的操作

改进

然而,由于您使用的是相当大的数字,因此使用浮点数而不是双精度可能会有所帮助。此外,将x1转换为您的小系统的原点可能会改善它。 最后,希望有一个更合适的数据结构

// using x1 as origin:
double x1x0 = 0, x1y0 = 0, x2x0 = x2x - x1x, x2y0 = x2y - x1y;

double x2x3x0 = 1;
// calculate y-value, using the fact that dot-product of orthogonal vectors is 0
double x2x3y0 = x2x0*x2x3x0 / (-1 * x2y0);
// calculate length of vector x2x3
double length_e_vec_x2_x30 = sqrt(pow(x2x3x0, 2) + pow(x2x3y0, 2));
// stretch vector to provided witdh
x2x3x0 = x2x3x0*width / length_e_vec_x2_x30;
x2x3y0 = x2x3y0*width / length_e_vec_x2_x30;
// since x2x3 and x1x4 are equal, simple addition remains
double x3x0, x3y0, x4x0, x4y0;
x3x0 = x2x0 + x2x3x0;
x3y0 = x2y0 + x2x3y0;
x4x0 = x1x0 + x2x3x0;
x4y0 = x1y0 + x2x3y0;

// check results
cout << "X1: " << x1x0 << "/" << x1y0 << endl;
cout << "X2: " << x2x0 << "/" << x2y0 << endl;
cout << "X3: " << x3x0 << "/" << x3y0 << endl;
cout << "X4: " << x4x0 << "/" << x4y0 << endl;

// verify results
cout << "Dotproduct should be 0: " << (x2x0*x2x3x0) + (x2y0*x2x3y0) << endl;

// compare results (adding offset before comparing):
cout << "X3 to X30: " << x3x0+x1x-x3x << "/" << x3y0+x1y-x3y << endl;
cout << "X4 to X40: " << x4x0 +x1x-x4x << "/" << x4y0 +x1y-x4y << endl;
现在,使用浮点输出:

X1: 629434/5.4762e+06
X2: 629443/5.47612e+06
X3: 629500/5.47613e+06
X4: 629491/5.4762e+06
Dotproduct should be 0: 0
X1: 0/0
X2: 8.8125/-77
X3: 65.4428/-70.5188
X4: 56.6303/6.48123
Dotproduct should be 0: 0
X3 to X30: 0/0
X4 to X40: 0/0
让整件事情变得不那么混乱:

using namespace std;

class vector2D
{
protected:
    bool equal(vector2D& param) { return this->X == param.X && this->Y == param.Y; }
    vector2D absAlVal() { return vector2D(abs(X), abs(Y)); }

public:
    float X, Y;

    vector2D(float x, float y) : X(x), Y(y) {};
    vector2D() : X(0), Y(0) {};

    vector2D operator+ (vector2D& param) { return vector2D(this->X+param.X,this->Y+param.Y); }
    vector2D operator- (vector2D& param) { return vector2D(this->X - param.X, this->Y - param.Y); }
    bool operator!=(vector2D& param) { return this->equal(param); }


    vector2D getUnitVector()
    {
        return vector2D(this->X / this->getLength(), this->Y / this->getLength());
    }
    bool parallel(vector2D& param) { return (this->getUnitVector()).equal(param.getUnitVector()); }
    bool colinear(vector2D& param) { return (this->getUnitVector().absAlVal()).equal(param.getUnitVector().absAlVal()); }

    float dotproduct(vector2D vec)
    {
        return this->X * vec.X + this->Y * vec.Y;
    }
    vector2D dotproduct(float scalar)
    {
        return vector2D(this->X * scalar, this->Y * scalar);
    }
    float getLength(void)
    {
        return sqrt(pow(this->X, 2) + pow(this->Y, 2));
    }

};

void main()
{
    // get coords from provided input
    float x1x = 629434.24373957072, x1y = 5476196.7595944777, x2x = 629443.08914538298, x2y = 5476120.1852802411;
    float width = 35;

    // Build vectors
    vector2D X1 = vector2D(x1x, x1y), X2 = vector2D(x2x, x2y), X3, X4, X2X3, X1X2=X2-X1;
    // assum x-direction for X2X3 is positive, chosing 1
    X2X3.X = 1;
    // calculate y-direction using dot-product
    X2X3.Y = X1X2.X*X2X3.X / (-1 * X1X2.Y);
    //check if assumtion is correct:
    cout << "Evaluate wether vector has been build accordingly or not:" << endl;
    cout << "Dotproduct of X1X2 * X2X3 should be 0 -> Result:" << X1X2.dotproduct(X2X3) << endl;
    // stretch X2X3 to width
    X2X3=X2X3.getUnitVector().dotproduct(width);

    // Create X3 and X4 by simple addition:
    X3 = X2 + X2X3;
    X4 = X1 + X2X3;

    // print Points:
    cout << "Summary of Points X / Y coordinates:" << endl;
    cout << "X1: " << X1.X << "/" << X1.Y << endl;
    cout << "X2: " << X2.X << "/" << X2.Y << endl;
    cout << "X3: " << X3.X << "/" << X3.Y << endl;
    cout << "X4: " << X4.X << "/" << X4.Y << endl;
    // compare sides
    cout << "\n" << "Lenght of sides:" << endl;
    cout << "X1X2: " << (X2 - X1).getLength() << " -> should be same length as X3X4" << endl;
    cout << "X2X3: " << (X3 - X2).getLength() << " -> should be same length as X4X1 and with, which is:" << width << endl;
    cout << "X3X4: " << (X4 - X3).getLength() << " -> should be same length as X1X2" << endl;
    cout << "X4X1: " << (X1 - X4).getLength() << " -> should be same length as X2X3, which is:" << width << endl;
}
使用名称空间std;
类向量2D
{
受保护的:
boolequal(vector2D¶m){返回this->X==param.X&&this->Y==param.Y;}
vector2D absAlVal(){返回vector2D(abs(X),abs(Y));}
公众:
浮动X,Y;
向量2d(float x,float y):x(x),y(y){};
向量2d():X(0),Y(0){};
vector2D操作符+(vector2D¶m){返回vector2D(this->X+param.X,this->Y+param.Y);}
vector2D操作符-(vector2D¶m){返回vector2D(this->X-param.X,this->Y-param.Y);}
布尔运算符!=(vector2D¶m){返回此->相等(param);}
vector2D getUnitVector()
{
返回向量2d(this->X/this->getLength(),this->Y/this->getLength());
}
bool并行(vector2D¶m){return(this->getUnitVector()).equal(param.getUnitVector());}
布尔共线(vector2D¶m){return(this->getUnitVector().absAlVal()).equal(param.getUnitVector().absAlVal());}
浮点点积(矢量2D矢量)
{
返回此->X*vec.X+此->Y*vec.Y;
}
矢量2D点积(浮点标量)
{
返回向量2D(此->X*标量,此->Y*标量);
}
浮动长度(无效)
{
返回sqrt(pow(this->X,2)+pow(this->Y,2));
}
};
void main()
{
//从提供的输入获取坐标
浮点数x1x=629434.24373957072,x1y=5476196.7595944777,x2x=629443.08914538298,x2y=5476120.1852802411;
浮动宽度=35;
//构建向量
向量2d-X1=vector2D(x1x,x1y),X2=vector2D(x2x,x2y),X3,X4,X2X3,X1X2=X2-X1;
//假设X2X3的x方向为正,选择1
X2X3.X=1;
//使用点积计算y方向
X2X3.Y=X1X2.X*X2X3.X/(-1*X1X2.Y);
//检查假设是否正确:
cout给定一个向量
(x,y)
,方向
(y,-x)
相对于它顺时针旋转90度。这正是我们从
x1->x2
获得侧面
x1->x4
的方向所需要执行的旋转

// input point struct
struct point { double x, y; };

// pass in output points by reference
void calculate_other_points(
   const point& x1, const point& x2, // input points x1 x2
   double w,                         // input width
   point& x3, point& x4)             // output points x3 x4
{
   // span vector x1 -> x2
   double dx = x2.x - x1.x,
          dy = x2.y - x1.y;
   // height
   double h = hypot(dx, dy);

   // perpendicular edge x1 -> x4 or x2 -> x3
   double px =  dy * (w / h),
          py = -dx * (w / h);

   // add onto x1 / x2 to obtain x3 / x4
   x4.x = x1.x + px; x4.y = x1.y + py;
   x3.x = x2.x + px; x3.y = x2.y + py;
}

请注意,我的代码原则上与前面的答案类似,但经过了一些优化,并且(希望如此)解决了方向问题。

您已经在这里呆了足够长的时间,知道您需要展示您已经尝试了什么以及您遇到了什么问题。我想我已经很清楚了:我尝试实现了上面提到的两种解决方案,但是我遇到了问题,因为点有点偏离。比如说,我提到的50米中有3米。可能是因为这些米的旋转我被困在这里是因为我想找到