Trilater votre position

11

introduction

Imaginez que vous êtes sur un plan cartésien bidimensionnel et que vous souhaitez déterminer votre position sur celui-ci. Vous connaissez 3 points sur cet avion et votre distance à chacun d'eux. Bien qu'il soit toujours possible de calculer votre position à partir de cela, faire cela dans votre tête est assez difficile. Vous décidez donc d'écrire un programme pour cela.

Le défi

Étant donné 3 points et votre distance par rapport à eux, sortez les coordonnées de votre position.

  • L'entrée et la sortie peuvent être dans n'importe quel format pratique, y compris en utilisant des nombres complexes au lieu de vrais. Veuillez préciser dans votre réponse le format que vous utilisez.
  • Vous obtiendrez toujours exactement 3 points distincts avec leur distance à vous.
  • Les coordonnées et les distances seront flottantes avec une précision arbitraire. Votre sortie doit être correcte avec 3 décimales. L'arrondi dépend de vous. Veuillez préciser dans votre réponse.
  • Vous pouvez supposer que les trois points ne sont pas colinéaires, il y aura donc toujours une solution unique.
  • Vous n'êtes pas autorisé à renforcer brutalement la solution.
  • Vous ne pouvez pas utiliser de modules internes qui banalisent ce problème particulier. Les extensions pour les normes vectorielles, etc. sont cependant autorisées.

Astuce pour commencer:

Pensez à un cercle autour de chacun de ces 3 points avec leur distance à vous comme rayon.

Règles

Cas de test

Le format d'entrée pour un point ici est [[x,y],d]avec xet yétant les coordonnées et détant la distance à ce point. Les 3 de ces points sont classés dans une liste. La sortie sera xpuis ydans une liste.

[[[1, 2], 1.414], [[1, 1], 2.236], [[2, 2], 1.0]] -> [2, 3]
[[[24.234, -13.902], 31.46], [[12.3242, 234.12], 229.953], [[23.983, 0.321], 25.572]] -> [-1.234, 4.567]
[[[973.23, -123.221], 1398.016], [[-12.123, -98.001], 990.537], [[-176.92, 0], 912.087]] -> [12.345, 892.234]

Vous pouvez générer des cas de test supplémentaires avec ce programme Pyth . L'emplacement va sur la première ligne de l'entrée et les 3 points sont sur les 3 lignes suivantes.

Codage heureux!

Denker
la source
Parce qu'il doit s'adapter à un plan cartésien bidimensionnel, le code doit être aussi court que possible.
wizzwizz4
Vous utilisez évidemment des résultats inexacts qui peuvent encore créer de l'ambiguïté, comment devons-nous gérer cela?
flawr
@flawr Supposons simplement que tous les résultats sont exacts et uniques. Votre programme devrait fonctionner pour les cas avec très peu de décimales, ne vous inquiétez pas de l'ambiguïté. Je vais nettoyer le défi quand je serai à la maison.
Denker
Étant donné que la réponse acceptée n'est en fait qu'une calculatrice graphique, je mentionnerai qu'il existe une solution à 96 octets dans TI-Basic (version 68k). Pour clarifier, est-ce que solve(étant donné trois équations de cercle) banaliser le problème? Je pensais que c'était le cas, mais si vous êtes d'accord avec de telles choses, je vais aller de l'avant et l'afficher.
Fox

Réponses:

4

Desmos, 122 octets

Utilisation en ligne . Copiez + collez chaque équation dans une boîte d'équation, cliquez sur "ajouter tout" pour chaque boîte, puis cliquez sur le point d'intersection, puis entrez chaque valeur selon le cas. chacun de A, B, et Csont des distances pour les points (a,b), (c,d), et (E,f), respectivement. Pour obtenir une racine carrée dans la valeur, saisissez sqrtensuite la valeur dans la zone.

\left(x-a\right)^2+\left(y-b\right)^2=AA
\left(x-c\right)^2+\left(y-d\right)^2=BB
\left(x-E\right)^2+\left(y-f\right)^2=CC

Vérifiez le premier cas de test .

Ou vous pouvez jeter un œil ici:

cercles!

Conor O'Brien
la source
Cela a l'air plutôt sympa, mais cela satisfait-il nos critères de langages de programmation? Cela ressemble à un outil de traçage pour moi, je ne l'ai jamais utilisé, donc je peux me tromper.
Denker
1
@DenkerAffe J'ai déjà posé une question à ce sujet sur Meta avant , et cela compte en effet.
Conor O'Brien
2
Bon, alors j'ai mon vote positif :)
Denker
Je conteste le nombre d'octets. Vous obtenez gratuitement en cliquant sur le point d'intersection, ce qui ne semble pas correct.
lirtosiast
@lirtosiast Je dirais que le point est toujours là par définition et déclare en outre que le PO a déclaré que ce type d'interaction était correct. Si, toutefois, vous pensez qu'il devrait y avoir une sanction, je suis ouvert aux suggestions.
Conor O'Brien
4

C, 362 348 345 octets

Entrée est donnée comme une séquence de flotteurs séparés par des espaces sur l' entrée standard: x1 y1 d1 x2 y2 d2 x3 y3 d3. La sortie est similaire sur stdout: x y.

#define F"%f "
#define G float
#define T(x)(b.x*b.x-a.x*a.x)
typedef struct{G a;G b;G c;}C;G f(C a,C b,G*c){G x=b.b-a.b;*c=(T(a)+T(b)-T(c))/x/2;return(a.a-b.a)/x;}main(){C a,b,c;G x,y,z,t,m;scanf(F F F F F F F F F,&a.a,&a.b,&a.c,&b.a,&b.b,&b.c,&c.a,&c.b,&c.c);x=f(a,a.b==b.b?c:b,&y);z=f(b.b==c.b?a:b,c,&t);m=t-y;m/=x-z;printf(F F"\n",m,x*m+y);}

Cest un type de structure dont les membres sont une coordonnée x a, une coordonnée y bet une distance (rayon) c. La fonction fprend deux Cstructures et un pointeur sur un flotteur, et détermine la ligne à laquelle les C(cercles) se croisent. L'ordonnée à l'origine de cette ligne est placée dans le flotteur pointé et la pente est renvoyée.

Le programme fait appel fà deux paires de cercles, puis détermine l'intersection des lignes produites.

Renard
la source
Puisque nous avons précisé que les entrées ne sont pas colinéaires, les lignes fproduites ne seront jamais parallèles. Les tests visent à s'assurer qu'ils ne sont pas non plus verticaux, car j'utilise une forme d'interception de pente. De cette façon, il y a toujours exactement une réponse.
Fox
2

Python - 172

Prend l'entrée comme une liste de tuples de forme (x, y, d). Faites-moi savoir si vous voyez un moyen de jouer au golf plus loin, j'ai l'impression qu'il doit y en avoir mais je ne peux pas le découvrir!

import numpy as N
def L(P):
    Z=[p[2]**2-p[0]**2-p[1]**2 for p in P];return N.linalg.solve([[P[i][0]-P[0][0],P[i][1]-P[0][1]]for i in[1,2]],[(Z[0]-Z[i])*0.5 for i in [1,2]])
RT
la source
Vous pouvez omettre certains espaces ici. Quelque chose comme -1 if 1 else 1peut devenir -1if 1else 1par exemple. Cela fonctionne également avec des crochets. Il y a quelques endroits où vous pouvez en profiter. Est également .5le même que 0.5.
Denker