2009-08-29 6 views
10

Gegeben eine Linie mit dem ersten Endpunkt P (x1, y1) ist ein anderer Endpunkt unbekannt, der einen Kreis schneidet, der im Ursprung mit dem Radius R an nur einem Punkt (Tangente) T (x2, y2) liegt. Wer weiß, wie man den Punkt T bekommt? Danke im Voraus!Suchen Sie einen Tangentenpunkt auf dem Kreis?

+0

Wie ist es eine Zeile, wenn Sie nur einen Endpunkt haben? – obelix

+0

er hat zwei verschiedene Endpunkte, weil er weiß, dass die Linie tangential ist. – andandandand

+1

dmindreader Sie bekommen wirklich meinen Standpunkt. Vielen Dank. –

Antwort

1

Verwenden Sie die x, y Koordinaten der sich schneidenden Gleichungen (die des Kreises und die der Linie). Das ist der Punkt.

Wenn Sie nur einen Endpunkt zum Zeichnen der Linie haben, erhalten Sie zwei verschiedene Punkte, da es zwei verschiedene Tangenten gibt, eine nach oben und eine nach unten.

9

Nehmen Sie R als Radius des Kreises und D den Abstand vom äußeren Punkt zum Mittelpunkt des Kreises, so dass D > R.

Die tanget Linie und Winkel von \alpha mit der Linie macht den äußeren Punkt und das Zentrum verbindet, wo

\alpha = arcsin(R/D) 

Die Linie, die die Außenstelle (P) und das Zentrum verbindet (C) mit einem Winkel die horizontal von

\beta = arctan((C_y - P_y)/(C_x - P_x)) 

, dass Sie den Winkel der Tangente mit der horizontalen als

gibt 210
\theta = \beta +/- \alpha 

Beachten Sie die Mehrdeutigkeit.

Die Länge der Tangente Segment ist

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

, die alles, was Sie brauchen.

+1

** @ HanWu: ** Beim Zeichnen eines Bildes und Überprüfung mich selbst, bekomme ich immer noch 'arcsin'. Sie würden 'Arccos' für den Winkel zwischen der Verbindungslinie (CP) und dem Radius (CT) verwenden. – dmckee

+0

arcsin ist korrekt: sine (alpha) = entgegengesetzt (R)/hypotenuse (D) – Argalatyr

+0

\ alpha = arcsin (R/D) sollte sein \ alpha = arccos (R/D) –

0

Eine andere Lösung; weniger elegant als dmindreader`s, aber vielleicht einfacher zu verstehen:

Sie wissen, dass der Punkt T auf dem Kreis ist und dass die Linie OT ist senkrecht zur Linie PT

, die Ihnen

abs(O - T) = R 
dotProduct(O - T, P - T) = 0 
gibt
32

Gegeben eine Linie mit dem ersten Endpunkt P (x1, y1) ist ein anderer Endpunkt unbekannt, schneiden Sie einen Kreis, der im Ursprung mit dem Radius R an nur einem Punkt (Tangente) T (x2, y2) liegt. Wer weiß, wie man den Punkt T bekommt?

Einige der anderen Lösungen scheinen ein bisschen wie Overkill. Ich denke, der einfachste Weg besteht darin, zu bemerken, dass dies ein rechtwinkliges Dreieck ist, mit den Eckpunkten P, T und O (der Ursprung). Der Winkel PTO ist der rechte Winkel, da eine Tangente immer im rechten Winkel zu einem Radius steht.

Sie kennen die Länge von TO, weil es von Länge r ist und einen Scheitelpunkt am Ursprung hat; Sie wissen OP, weil Sie wissen, wo O und P ist. Bei zwei Seiten eines rechtwinkligen Dreiecks ist es leicht, die Länge und Richtung der dritten Seite zu finden. Das sind Hausaufgaben, also überlasse ich den Rest dem Leser als Übung.

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

Es gibt zwei mögliche Richtungen für TO, da der Punkt T‘ist auch ein gültiger Tangentenpunkt, so dass Sie zwei kongruente Dreiecke haben.

+18

+1 für die Ascii-Kunst! – ThibThib

+1

Dies ist bekannt als das [Thales Theorem] (http://en.wikipedia.org/wiki/Thales%27_theorem). – JCM

+0

@JCM Ich verstehe nicht, wie das Thales Theorem ist. Thale würde nur sagen, dass "OP" der Durchmesser des Umkreises für "OPT" ist. –

2

Es ist nicht offensichtlich für mich, dass dies Hausaufgaben sind, aber ich mag die Intuition, dass ein rechtwinkliges Dreieck definiert ist. Trotzdem wird es bei dieser Lösung etwas Algebra geben.

Ein anderer Ansatz, der realisierbar scheint, besteht darin, das Problem einfach als Lösung zweier Gleichungen in zwei Unbekannten zu definieren. Das heißt, die Gleichung eines Kreises, zentriert bei (0,0), mit dem Radius R ist

x^2 + y^2 = R^2 

die Gleichung einer Linie, die durch den Punkt (xt, yt), mit (unbekannt) Steigung S ist

(y - yt) = S*(x - xt) 

Lösen Sie das System von zwei Gleichungen für den Schnittpunkt. Abhängig von dem Wert von S gibt es für dieses Gleichungspaar null, eine oder zwei Lösungen. Es wird sich auch herausstellen, dass es zwei Werte von S gibt, so dass die Lösung einzigartig ist. Lösen Sie für diese zwei Werte von S, die die Lösung eindeutig machen, und stellen Sie dann den Schnittpunkt (xt, yt) wieder her. Ich werde die eigentliche Lösung nicht gründlich durchgehen, wenn das Hausaufgaben sind, aber dieser Teil ist Trivialalgebra.

Mein Punkt ist, dass dieser algebraische Ansatz eine andere Möglichkeit ist, die Lösung des Problems der rechnerischen Geometrie zu betrachten. Es hebt einen interessanten Punkt darin hervor, dass es zwei Linien gibt, die den Kreis an einem Tangentenpunkt schneiden, und dass, wenn eine Linie an einem Tangentenpunkt schneidet, es einen einzelnen Schnittpunkt gibt.

Ein Fehler dieses Ansatzes ist, dass aufgrund einer Singularität für einige Probleme fehlschlägt. D.h., wenn die Linie mit der Steigung S vertikal ist, dann ist S nicht definiert. Andere Ansätze, die sich auf einfache Abstände und den Satz des Pythagoras stützen, sind robust gegenüber diesem Ereignis.

14

Alles, was Sie brauchen, ist in Dmckee's Antwort, aber wenn Sie etwas Code interessiert, überprüfen Sie diese Implementierung mit Javascript und HTML-Canvas.

Voll Beispiel: http://jsfiddle.net/zxqCw/1/

// find tangents 
dx = cx - px; 
dy = cy - py; 
dd = Math.sqrt(dx * dx + dy * dy); 
a = Math.asin(radius/dd); 
b = Math.atan2(dy, dx); 

t = b - a 
ta = { x:radius * Math.sin(t), y:radius * -Math.cos(t) }; 

t = b + a 
tb = { x:radius * -Math.sin(t), y:radius * Math.cos(t) }; 
+0

Was steht für x: radius? – 130nk3r5

+1

Radius = Radius des Kreises. ta = ein Objekt mit den Eigenschaften x und y (im Grunde ein Punkt). Um Ihre Frage zu beantworten, stellt x: radius nicht viel für sich selbst dar. Der Code definiert den Wert von ta.x mit x = Radius * Math.sin (t). Bitte vergewissern Sie sich, dass Sie auf die jsfiddle verweisen, um ein funktionierendes Beispiel zu sehen. – imbrizi

+0

Ich versuche, dies in C# -Code zu konvertieren ....und ich konnte nicht herausfinden, was x: radius ist ... Aber ich las den Code falsch .... Ich missverstanden es für ein Objekt x mit Wertradius ... wo es einfach der Wert x von ta war. THanks;) – 130nk3r5

3
  1. Sie Richtung von Vektor finden DX wenn Sie Vektor drehen DO durch Winkel alpha (Winkel alpha gefunden als asin (len (OX)/len (DO)), die einfach arcsinus des Radius über Hypotenuse)

  2. können Sie die Länge von Vektor DX trivialer folgend finden: sqrt (len (DO) * len (DO) - len (OX) * len (OX))

  3. Da die Richtung und die Länge des Vektors DX, können Sie den Wert von PunktX finden.Ein Ansatz wäre, DX zu normalisieren und es mit der Länge davon zu multiplizieren.

auto dist = D.Distance(O); 
auto side = sqrt(dist*dist - rad*rad) 
auto line = Vector2D(D, O); 
line.Rotate(asin(rad/dist)); //get the direction 
line.Normalize();    //set length to 1 
line*=side;     //we have the direction, now get length 
Point2D X = D + line; 

P. S. Man beachte, dass es auch eine zweite Tangente, die gefunden wird DO durch Drehen von minus alpha

Image demonstrating the algo

4

imbrizi Antwort, dass die Mitte des Kreises geht davon (0,0) ist.

Dies ist die richtige Antwort in Objective 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; 
} 
+0

Dank Ihrer Lösung hat mein Problem gelöst. ;) – crypt

1

Normalerweise verwende ich Maple-Software, um solche Probleme zu lösen. Es kann sogar C-Code aus diesen Gleichungen erzeugen.

enter image description here

Hier ist der Ausgang:

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; 

Offensichtlich müssen Sie die Variablen float oder double hinzufügen, überprüfen auch für negative Wert vor der Quadratwurzel.