Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/14.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
Math 在圆上找到一个切点?_Math_Geometry_Line - Fatal编程技术网

Math 在圆上找到一个切点?

Math 在圆上找到一个切点?,math,geometry,line,Math,Geometry,Line,给定一条具有第一个端点p(x1,y1)的直线,另一个端点未知,与位于原点的圆相交,半径R仅在一个点(切线)T(x2,y2)处。有人知道如何得到T点吗?提前谢谢 使用相交方程式的x、y坐标(圆和线的坐标)。这就是重点 如果你只有一个端点来画这条线,你会得到两个不同的点,因为会有两条不同的切线,一条向上,一条向下。以R为圆的半径,以D为外点到圆心的距离,这样D>R tanget线与连接外部点和中心的线构成\alpha的角度,其中 \alpha = arcsin(R/D) 连接外部点(p)和中心(C

给定一条具有第一个端点p(x1,y1)的直线,另一个端点未知,与位于原点的圆相交,半径R仅在一个点(切线)T(x2,y2)处。有人知道如何得到T点吗?提前谢谢

使用相交方程式的x、y坐标(圆和线的坐标)。这就是重点


如果你只有一个端点来画这条线,你会得到两个不同的点,因为会有两条不同的切线,一条向上,一条向下。

R
为圆的半径,以
D
为外点到圆心的距离,这样
D>R

tanget线与连接外部点和中心的线构成
\alpha
的角度,其中

\alpha = arcsin(R/D)
连接外部点(
p
)和中心(
C
)的线与

\beta = arctan((C_y - P_y)/(C_x - P_x))
这将为您提供切线与水平面的角度

\theta = \beta +/- \alpha
请注意歧义

切线段的长度为

L = sqrt(D^2 - R^2)

这就是你所需要的。

另一种解决方案;没有dmindreader的优雅,但可能更容易理解:

您知道点
T
在圆上,线
OT
垂直于线
PT

那就给你

abs(O - T) = R
dotProduct(O - T, P - T) = 0
给定一条具有第一个端点p(x1,y1)的直线,另一个端点未知,与位于原点的圆相交,半径R仅在一个点(切线)T(x2,y2)处。有人知道如何得到T点吗

其他一些解决方案似乎有点过分了。我认为最简单的方法就是注意这是一个直角三角形,顶点是P,T和O(原点)。角度PTO是直角,因为切线始终与半径成直角

你知道
的长度,因为它的长度
r
,并且在原点有一个顶点;你知道
OP
,因为你知道
O
P
在哪里。给定直角三角形的两条边,很容易找到第三条边的长度和方向。这是家庭作业,所以我将把剩下的作为练习留给读者

                    __...------__    T(x2, y2)                      
               _.-''             -(+)
            ,-'                   |----             
          ,'                     |     ----
        ,'                      |       '  ----
       /                       |         `     ----       
      /                       |           `.       ----   
     /                       |             \           ----
    |                       |               |              ----
    |                      |                 |                  ----
    |                     |                  |                      ----
    |                   (+)---------------------------------------------(+) P (x1,y1)
    |                                        .'        
    |                    O                   |         
     |                                      .'         
      \                                     /          
       \                                  ,'           
        `                                /             
         '.                            ,'              
           '-.                      _,'             
              '-._              _,(+)  T'(x3, y3)                   
                  '`--......---'                       

有两个可能的方向,因为点T'也是一个有效的切点,所以有两个全等三角形。

我不清楚这是家庭作业,但我喜欢定义直角三角形的直觉。即使如此,也会有一些代数与这个解决方案

另一种似乎可行的方法是简单地将问题定义为两个未知数中两个方程的解。也就是说,以(0,0)为中心,半径为R的圆的方程为

x^2 + y^2 = R^2
通过点(xt,yt)的直线方程(未知)斜率为S

(y - yt) = S*(x - xt)
求解交点的两个方程组。根据S的值,这对方程将有零个、一个或两个解。结果还表明,S有两个值,因此解决方案是唯一的。求出使解唯一的两个S值,然后恢复交点(xt,yt)。如果这是家庭作业,我不会深入讨论实际的解决方案,但那部分是琐碎的代数

我的观点是,这种代数方法是另一种看待计算几何问题解决方案的方法。它突出显示了一个有趣的点,即有两条直线在切点处与圆相交,当一条直线在切点处相交时,有一个交点


这种方法的一个缺陷是由于某些问题的奇异性而失败。即,当坡度为S的直线垂直时,则S未定义。其他依赖于简单距离和毕达哥拉斯定理的方法对该事件具有鲁棒性。

您需要的只是dmckee的答案,但是如果您需要一些代码,请使用Javascript和HTML画布检查此实现

完整示例:

  • 如果按角度alpha旋转向量DO,则可以找到向量DX的方向 (α角为asin(len(OX)/len(DO)),即斜边上的半径弧)

  • 你可以找到向量DX的长度如下:sqrt(len(DO)*len(DO)-len(OX)*len(OX))

  • 给定向量DX的方向和长度,可以找到点X的值。一种方法是将DX标准化并乘以其长度

  • 注意,还有第二条切线,通过旋转DO减去alpha


    imbrizi的答案假设圆的中心是(0,0)

    这是目标C中的正确答案:

    - (NSArray *)pointsTangentToCircleWithCenter:(CGPoint)centerPoint
                                          radius:(CGFloat)radius
                                      outerPoint:(CGPoint)outerPoint {
    
        float dx = centerPoint.x - outerPoint.x;
        float dy = centerPoint.y - outerPoint.y;
        float dd = sqrt(dx*dx + dy*dy);
        float a = asinf(radius / dd);
        float b = atan2f(dy, dx);
        float t1 = b - a;
        CGPoint tangentPoint1 = CGPointMake(centerPoint.x + radius*sinf(t1), 
                                            centerPoint.y + radius*-cosf(t1));
    
        float t2 = b + a;
        CGPoint tangentPoint2 = CGPointMake(centerPoint.x + radius*-sinf(t2), 
                                            centerPoint.y + radius*cosf(t2));
    
        NSArray *points = @[
                            [NSValue valueWithCGPoint:tangentPoint1],
                            [NSValue valueWithCGPoint:tangentPoint2]
                            ];
        return points;
    }
    

    我通常使用Maple软件来解决这些问题。它甚至可以从这些方程生成C代码

    以下是输出:

    t1 = v_x * v_x;
    t2 = t1 * t1;
    t3 = v_y * v_y;
    t6 = sqrt(t1 * t3 - t1 + t2);
    t7 = v_y + t6;
    t9 = 0.1e1 / (t1 + t3);
    t13 = 0.1e1 / v_x;
    x1 = -(t7 * t9 * v_y - 0.1e1) * t13;
    y1 = t7 * t9;
    t16 = (-v_y + t6) * t9;
    x2 = -(-t16 * v_y - 0.1e1) * t13;
    y2 = -t16;
    

    显然,你需要给变量加上float或double,在求平方根之前还要检查负值。

    如果你只给了一个端点,那它怎么会是一条线呢?他有两个不同的端点,因为他知道这条线是相切的。dmindreader你真的明白我的意思了。谢谢。这是数学,不是编程-related@HanWu:在画一幅画并检查自己时,我仍然得到
    arcin
    。对于连接线(CP)和半径(CT)之间的角度,可以使用
    arccos
    。Arccin是正确的:正弦(alpha)=对边(R)/斜边(D)\alpha=arccos(R/D)应该是\alpha=arccos(R/D)。我正在考虑它,它似乎不正确。具体地说,不存在某些正弦等于R/D(或余弦)的配置。你想让D变成斜边,但斜边只是D
    - (NSArray *)pointsTangentToCircleWithCenter:(CGPoint)centerPoint
                                          radius:(CGFloat)radius
                                      outerPoint:(CGPoint)outerPoint {
    
        float dx = centerPoint.x - outerPoint.x;
        float dy = centerPoint.y - outerPoint.y;
        float dd = sqrt(dx*dx + dy*dy);
        float a = asinf(radius / dd);
        float b = atan2f(dy, dx);
        float t1 = b - a;
        CGPoint tangentPoint1 = CGPointMake(centerPoint.x + radius*sinf(t1), 
                                            centerPoint.y + radius*-cosf(t1));
    
        float t2 = b + a;
        CGPoint tangentPoint2 = CGPointMake(centerPoint.x + radius*-sinf(t2), 
                                            centerPoint.y + radius*cosf(t2));
    
        NSArray *points = @[
                            [NSValue valueWithCGPoint:tangentPoint1],
                            [NSValue valueWithCGPoint:tangentPoint2]
                            ];
        return points;
    }
    
    t1 = v_x * v_x;
    t2 = t1 * t1;
    t3 = v_y * v_y;
    t6 = sqrt(t1 * t3 - t1 + t2);
    t7 = v_y + t6;
    t9 = 0.1e1 / (t1 + t3);
    t13 = 0.1e1 / v_x;
    x1 = -(t7 * t9 * v_y - 0.1e1) * t13;
    y1 = t7 * t9;
    t16 = (-v_y + t6) * t9;
    x2 = -(-t16 * v_y - 0.1e1) * t13;
    y2 = -t16;