如何调整椭圆的大小,使其始终接触左右边界? 我使用下面的C++代码来计算在画布上画出的椭圆外面的360个点。我通过选择一条左右边来设置椭圆的大小,即x1,y1,x2,y2。当使用水平长轴(0度)计算椭圆时,椭圆会接触左右边缘。当我计算长轴为45度的椭圆时,椭圆的顶部和底部不再接触左右边缘。我需要画一个角度的椭圆,使它接触左右边界。要做到这一点,我需要画更大的椭圆,但我不知道如何计算更大的尺寸。有没有办法计算更大尺寸的椭圆,使成角度的椭圆接触原始的左右边界

如何调整椭圆的大小,使其始终接触左右边界? 我使用下面的C++代码来计算在画布上画出的椭圆外面的360个点。我通过选择一条左右边来设置椭圆的大小,即x1,y1,x2,y2。当使用水平长轴(0度)计算椭圆时,椭圆会接触左右边缘。当我计算长轴为45度的椭圆时,椭圆的顶部和底部不再接触左右边缘。我需要画一个角度的椭圆,使它接触左右边界。要做到这一点,我需要画更大的椭圆,但我不知道如何计算更大的尺寸。有没有办法计算更大尺寸的椭圆,使成角度的椭圆接触原始的左右边界,c++,geometry,C++,Geometry,现在我将系数添加到for循环中 //Calculate 360 points around edge of ellipse for (p=0; p<NUM_POINTS_PER_CONTOUR; p++) { phi = p*2*M_PI/(double)NUM_POINTS_PER_CONTOUR; x1 = Coeff * e.a * std::sin(phi); y1 = Coeff * e.b * std::cos(phi); x2 = x1 * std::cos(e.thet

现在我将系数添加到for循环中

//Calculate 360 points around edge of ellipse
for (p=0; p<NUM_POINTS_PER_CONTOUR; p++) {
phi = p*2*M_PI/(double)NUM_POINTS_PER_CONTOUR;  
x1 = Coeff * e.a * std::sin(phi);
y1 = Coeff * e.b * std::cos(phi);
x2 = x1 * std::cos(e.theta) + y1 * std::sin(e.theta);
y2 = y1 * std::cos(e.theta) - x1 * std::sin(e.theta);
x3 = x2 + e.x0;
y3 = y2 + e.y0;
if(p==0){
Canvas->MoveTo(x3, y3);
}
Canvas->LineTo(x3, y3);
}
结果是椭圆的最宽部分始终接触左右边界。这是最简单和最接近的答案。下图显示了一个65度的椭圆,调整后与边界接触


我认为,如果你看一下你的第一幅插图,你可以使用一个原点x,y,它在x和y两个方向上平分原始椭圆,这样你就有了沿着x和y轴的两条对称线。然后,您将在原始椭圆上有4个感兴趣的点,这些点将是椭圆与+x&-x轴以及+y&-y轴相交或接触的位置。这将为这个椭圆提供2个半径,短半径和长半径。您可以并且将需要使用这些工具进行参考和计算;旋转椭圆后,我想从它的原点中心点开始,你将需要使用一些三角和向量代数来确定向量长度与椭圆边缘点在45度旋转线上的差,旋转线与垂直线x2y1相交,x2y2找到这个距离一旦你知道这个距离,然后使用一些向量计算,你应该能够计算出这个椭圆的倾斜程度,直到它有一个边缘点接触到这条垂直线。你不必担心你的另一条垂直线x1y1,x2y1,因为我们从这个椭圆的原点平分线开始旋转,有两条对称线。您可以在预处理之前完成所有这些计算。一旦你有了所有旋转倾斜点的新坐标,你就可以刷新点的更新或绘图缓冲区。我将尝试用几张图片来演示这一点:


要找到P2-P1的距离应该相当容易。您应该已经知道垂直线的x值;求旋转线的y值应该很容易,因为你说它是45度旋转,它有一个斜率,这条线的方程是y=x。这将以最小的计算速度提供P2。要找到P1应该很容易,因为它再次沿着y=x的线,你知道这个椭圆长半径的大小。然后减去两点,得到这个距离。从那里,您可以使用此距离来了解沿y=x线倾斜或拉伸此椭圆的程度。然后重新计算所有点,并使用基于倾斜值的新计算点更新图形缓冲区。现在有两种方法来扭曲这一点;一种是短半径不变,只是变长了,看起来更拉伸,而另一种是成比例的倾斜,如果长半径变大,短半径也会成比例地变大。我将把它留给你来决定你想要如何倾斜这个物体。

我认为对你有帮助的是,如果你看一下你的第一幅插图,你可以使用一个原点x,y,它在x和y两个方向上平分原始椭圆,这样你沿着x和y轴有两条对称线。然后,您将在原始椭圆上有4个感兴趣的点,这些点将是椭圆与+x&-x轴以及+y&-y轴相交或接触的位置。这将为这个椭圆提供2个半径,短半径和长半径。您可以并且将需要使用这些工具进行参考和计算;旋转椭圆后,我想从它的原点中心点开始,你将需要使用一些三角和向量代数来确定向量长度与椭圆边缘点在45度旋转线上的差,旋转线与垂直线x2y1相交,x2y2找到这个距离一旦你知道这个距离,然后使用一些向量计算,你应该能够计算出这个椭圆的倾斜程度,直到它有一个边缘点接触到这条垂直线。你不必担心你的另一条垂直线x1y1,x2y1,因为我们从这个椭圆的原点平分线开始旋转,有两条对称线。您可以在预编程时进行所有这些计算 字母S。一旦你有了所有旋转倾斜点的新坐标,你就可以刷新点的更新或绘图缓冲区。我将尝试用几张图片来演示这一点:


要找到P2-P1的距离应该相当容易。您应该已经知道垂直线的x值;求旋转线的y值应该很容易,因为你说它是45度旋转,它有一个斜率,这条线的方程是y=x。这将以最小的计算速度提供P2。要找到P1应该很容易,因为它再次沿着y=x的线,你知道这个椭圆长半径的大小。然后减去两点,得到这个距离。从那里,您可以使用此距离来了解沿y=x线倾斜或拉伸此椭圆的程度。然后重新计算所有点,并使用基于倾斜值的新计算点更新图形缓冲区。现在有两种方法来扭曲这一点;一种是短半径不变,只是变长了,看起来更拉伸,而另一种是成比例的倾斜,如果长半径变大,短半径也会成比例地变大。如果你的直线相距一定距离d,对于偏心率为e的椭圆,半长轴a的长度可以由a=d/21-e^2*sin^2θ给出,其中θ是椭圆的旋转角度

例如,角度为0表示a=d/2,这在定义上是正确的。如果角度为pi/4或45度,则转换为a=d/2-e^2

我不完全确定这是否正确,但我会在一段时间内编辑这篇文章,这样你可以检查我的工作,如果你愿意的话

另外,如果你不知道,椭圆的偏心率可以由e^2=1-b/a^2给出,其中a和b分别是半长轴和半短轴长度。对于椭圆,它是介于0和1之间的值


编辑:修正公式

如果直线相距一定距离d,则对于偏心率为e的椭圆,半长轴a的长度可由a=d/2 1-e^2*sin^2θ给出,其中θ是椭圆的旋转角度

例如,角度为0表示a=d/2,这在定义上是正确的。如果角度为pi/4或45度,则转换为a=d/2-e^2

我不完全确定这是否正确,但我会在一段时间内编辑这篇文章,这样你可以检查我的工作,如果你愿意的话

另外,如果你不知道,椭圆的偏心率可以由e^2=1-b/a^2给出,其中a和b分别是半长轴和半短轴长度。对于椭圆,它是介于0和1之间的值

编辑:修正公式

以0,0为中心的椭圆,旋转tθ,具有x坐标方程

x = a * cos(phi) * cos(t) + b * sin(phi) * sin(t)
当导数为零x'=0时,达到左右极值点

在第一个方程中替换该值,并找到放大系数,极值半尺寸应等于半轴

Coeff * (a * cos(phiMax) * cos(t) + b * sin(phiMax) * sin(t)) = a
Coeff = a / (a * cos(phiMax) * cos(t) + b * sin(phiMax) * sin(t))   {2}
现在可以实现公式{1}和{2},并在计算中使用此系数,如下所示:

x1 = Coeff * e.a * std::sin(phi);
y1 = Coeff * e.b * std::cos(phi); 
以0,0为中心的椭圆,由tθ旋转,具有x坐标方程

x = a * cos(phi) * cos(t) + b * sin(phi) * sin(t)
当导数为零x'=0时,达到左右极值点

在第一个方程中替换该值,并找到放大系数,极值半尺寸应等于半轴

Coeff * (a * cos(phiMax) * cos(t) + b * sin(phiMax) * sin(t)) = a
Coeff = a / (a * cos(phiMax) * cos(t) + b * sin(phiMax) * sin(t))   {2}
现在可以实现公式{1}和{2},并在计算中使用此系数,如下所示:

x1 = Coeff * e.a * std::sin(phi);
y1 = Coeff * e.b * std::cos(phi); 

不熟悉计算几何,但有没有一种有效的方法让你验证椭圆曲线是否接触到侧面,给出椭圆曲线的大小?如果是的话,也许你可以做一个二进制搜索:不断调整椭圆的大小,如果它与边接触/相交,减小它的大小,否则增加它的大小,因为边界不是整数,你可以简单地运行它几百次,这样精度就足够高,最终的大小就是整数answer@shole ,是的,我可以找到一个带有for循环的答案,但它很慢,我不确定它是否正确。我希望有一个公式可以给出准确的答案。即使你得到了一个公式,因为你不是在处理整数,双精度/浮点数据类型也会有自己的精度问题,这取决于你需要多少精度。因此,使用或w/o公式不是主要考虑的问题,而是精度误差。使用循环进行200次二进制搜索,精度将远远高于1e-30,1e-30的精度非常高,基本上瓶颈还是数据类型精度。如果验证过程有效,则此方法是有效的。当然,使用公式会给你一个最好的O1算法:这是一个数学问题,可以得到直接的答案,也就是说,公式直接给出了b之后的距离
对于那个网站来说,这已经变成了一个可以接受的问题。数学中有一些工具可以编写数学公式——需要解释和给出解决方案——但这在数学中是不存在的。不熟悉计算几何,但有没有一种有效的方法可以让你验证椭圆是否接触侧面,给出椭圆的大小?如果是的话,也许你可以做一个二进制搜索:不断调整椭圆的大小,如果它与边接触/相交,减小它的大小,否则增加它的大小,因为边界不是整数,你可以简单地运行它几百次,这样精度就足够高,最终的大小就是整数answer@shole ,是的,我可以找到一个带有for循环的答案,但它很慢,我不确定它是否正确。我希望有一个公式可以给出准确的答案。即使你得到了一个公式,因为你不是在处理整数,双精度/浮点数据类型也会有自己的精度问题,这取决于你需要多少精度。因此,使用或w/o公式不是主要考虑的问题,而是精度误差。使用循环进行200次二进制搜索,精度将远远高于1e-30,1e-30的精度非常高,基本上瓶颈还是数据类型精度。如果验证过程有效,则此方法是有效的。当然,使用公式会给你一个最佳的O1算法:这是一个数学问题,可以得到直接的答案,也就是说,公式直接给出了该站点可以接受的问题后的距离。数学中有一些工具可以编写数学公式——需要解释并给出解决方案——但在SO中并不存在。这看起来是正确的。今天让我测试一下,今晚晚些时候我会问我是否有问题。我编辑了我的问题以显示你的答案是正确的。这看起来是正确的。今天让我测试一下,我会问今晚晚些时候我是否有问题。我编辑了我的问题以显示你的答案是正确的。