我需要找到一条线(其原点是椭圆'中心)与2D中的椭圆相交...我可以很容易地在圆上找到一个点,因为我知道一个角度F和圆的'半径( R):
x = x0 + R * cosF
y = y0 + R * sinF
但是我无法想象我应该如何处理椭圆...我知道它的尺寸(A& B),但找到参数T的方法是什么?!
x = x0 + A * cosT
y = y0 + B * sinT
根据我的理解,参数T(T角)离F角不远(在某些情况下大约+ -15度),但我无法计算如何计算!!!
如果有一颗善良的心灵,请帮我解决这个问题...
答案 0 :(得分:7)
椭圆的标准方程,位于0,0,是:
1 = (x)^2 / (a) + (y)^2 / (b)
其中a是水平轴上直径的1/2,b是垂直轴上直径的1/2。
你有一条线,假设一个等式:
y = (m)(x - x0) + y0
所以,让我们即插即用!
1 = (x)^2 / (a) + (m(x - x0) + y0)^2 / (b)
1 = x^2 / a + (mx + (y0 - mx0))^2 / b
1 = x^2 / a + (m^2 * x^2 + 2mx*(y0 - mx0) + (y0 - mx0)^2) / b
1 = x^2 / a + (m^2 x^2) / b + (2mx*(y0 - mx0) + (y0^2 - 2y0mx0 + m^2*x0^2)) / b
1 = ((x^2 * b) / (a * b)) + ((m^2 * x^2 * a) / (a * b)) + (2mxy0 - 2m^2xx0)/b + (y0^2 - 2y0mx0 + m^2*x0^2)/b
1 = ((bx^2 + am^2x^2)/(ab)) + (x*(2my0 - 2m^2x0))/b + (y0^2 - 2y0mx0 + m^2*x0^2)/b
0 = x^2*((b + a*m^2)/(ab)) + x*((2my0 - 2m^2x0)/b) + (((y0^2 - 2y0mx0 + m^2*x0^2)/b) - 1)
最后一个等式遵循标准二次方程的形式。
所以只需使用二次公式:
((b + a*m^2)/(ab))
((2my0 - 2m^2x0)/b)
and
(((y0^2 - 2y0mx0 + m^2*x0^2)/b) - 1)
获取交叉点的X值;然后,将这些值插入到原始线方程中以获得Y值。
祝你好运!答案 1 :(得分:3)
不要这样做。而是检查形成椭圆的方程式并形成一条直线并求解该组:
椭圆:(x/a)^2 + (y/b)^2 = 1
你的行:y = cx
你知道a,b和c,所以找到解决方案很容易。你会发现两个解决方案,因为这条线穿过椭圆两次。
编辑:注意我将椭圆的中心移动到(0,0)。它使一切变得更容易。只需将(x0,y0)添加到解决方案中即可。
答案 2 :(得分:1)
我为您的问题编写了一个C#代码,希望您能发现它有用。此代码中的距离函数计算空间中两点之间的欧氏距离。
wX
表示椭圆的水平无线电,wY
表示垂直无线电。
private PointF LineIntersectEllipse(PointF A, PointF B, float wX, float wY)
{
double dx = B.X - A.X;
double dy = B.Y - A.Y;
double theta = Math.Atan2(dy, dx);
double r = distance(A, B) - ((wX * wY) / Math.Sqrt(Math.Pow(wY * Math.Cos(theta), 2) + Math.Pow(wX * Math.Sin(theta), 2)));
return PointF((float)(A.X + r * Math.Cos(theta)), (float)(A.Y + r * Math.Sin(theta)));
}
答案 3 :(得分:1)
public Hits<float2> EllipseLineIntersection ( float rx , float ry , float2 p1 , float2 p2 )
{
Hits<float2> hits = default(Hits<float2>);
float2 p3, p4;
Rect rect = default(Rect);
{
rect.xMin = math.min(p1.x,p2.x);
rect.xMax = math.max(p1.x,p2.x);
rect.yMin = math.min(p1.y,p2.y);
rect.yMax = math.max(p1.y,p2.y);
}
float s = ( p2.y - p1.y )/( p2.x - p1.x );
float si = p2.y - ( s * p2.x );
float a = ( ry*ry )+( rx*rx * s*s );
float b = 2f * rx*rx * si * s;
float c = rx*rx * si*si - rx*rx * ry*ry;
float radicand_sqrt = math.sqrt( ( b*b )-( 4f * a * c) );
p3.x = ( -b - radicand_sqrt )/( 2f*a );
p4.x = ( -b + radicand_sqrt )/( 2f*a );
p3.y = s*p3.x + si;
p4.y = s*p4.x + si;
if( rect.Contains(p3) ) hits.Push( p3 );
if( rect.Contains(p4) ) hits.Push( p4 );
return hits;
}
public struct Hits<T>
{
public byte count;
public T point0, point1;
public void Push ( T val )
{
if( count==0 ) { point0 = val; count ++; }
else if( count==1 ) { point1 = val; count ++; }
else print("This structure can only fit 2 values");
}
}