Bonjour à tous,
Depuis quelque temps je bloque sur un problème où je n'arrive pas a trouver de solution.
Le but de ma recherche est d'arriver à trouver une formule/équation qui déterminerait la position d'un point (en X et en Y) en fonction d'une valeur.
Vous trouverez ci-dessous, la géométrie (en espérant qu'elle soit compréhensible).
Cette géométrie et composé de 3 rayon non identiques, tangent sur chaque extrémité.
Le rayon central pilote la totalité de la géométrie, qui est totalement contraint en plusieurs points avec les formules indiquées.
Je recherche donc à déterminer, en fonction de ma valeur de rayon programmé, une formule, qui déterminerait la position en X et en Y mon point B et mon point C.
Pour exemple, la formule pour déterminer la position de mon point A dans l'axe Y est : R*(7/5.5).
A savoir, mon rayon R programmé varie ente 0,2 et 2,0. Je rajoute un petit tableau des angle en fonction des rayons programmé.
J'ai moyen informatiquement de vérifier mes résultats (Via un logiciel de conception 3D) mais pas moyen d'arriver à traduire tout ça en formule.
C'est donc la première étape de mon problème général, mais je préfère aller petit à petit pour rester compréhensible et voir si j'arrive à continuer seul.
Rayon | Alpha | Beta |
1.8 | 8.5 | 2.5 |
1.6 | 8.25 | 3.25 |
1.4 | 8 | 4 |
1.2 | 7.75 | 4.75 |
1.0 | 7.5 | 5.5 |
0.8 | 7.25 | 6.25 |
0.6 | 7 | 7 |
0.4 | 6.75 | 7.75 |
salut
la courbe semble être constituée de deux segments de droites (portés par les axes) et d'un arc de cercle de rayon R1
en notant I(m, m) ses coordonnées (il semble qu'il soit sur la bissectrice (d'équation x = y)
son équation est donc (x - m)^2 + (y - m)^2 = R1^2
A est le point d'abscisse nulle donc son ordonnée vérifie m^2 + (y - m)^2 = R1^2
de même pour D mais en permutant abscisse et ordonnée
ensuite pour les points de l'arc de cercle (B ou C ... ou d'autre)
leur coordonnées sont solution du système
y = xtan a
(x - m)^2 + (y - m)^2 = R1^2
où a est l'angle (OD, OB) ou (OD, OC)
mais avant d'aller plus loin il faudrait plus de précision :
l'arc de cercle en est-il vraiment un ?
que sont tes angles alpha et beta ?
Merci de ta réponse rapide,
La géométrie est constitué de 3 morceau de rayon, qui ne sont pas égaux et dont leur point de jonction sont défini par l'angle Alpha pour le point B et Beta pour le point C.
Bonjour,
Je pensais comme carpediem...
Dans ton cas,il y a tellement de paramètres que tu peux continuer avec ton abaque .
D'après les données, les équations des arcs de cercles peuvent ètre bien définies, donc les coordonnées des points B et C. Est-ce le problème posé ?
Bonjour et merci de vos réponses,
Je recherche les coordonnées des points C et D avec une formule où j'aurais besoin de changer uniquement ma valeur du rayon programmé (exemple avec un rayon programmé a 1,20).
J'aurais donc 4 équations : une pour le point C en axe X, une pour le point C en axe Y, et de même pour le point D.
Bonjour,
Ce qui n'est pas clair, ce sont vos données initiales et la façon dont vous voulez faire les raccordememts. Par un arc de cercle ?
Voir aussi "courbe de Bézier" sur internet.
Cherchez-vous une solution géométrique pour ces raccordememts ?
Bonjour carpediem, ( et dpi)
S'il faut tracer un cercle tangent à deux cercles donnés, on sait faire ...
Il faut trouver les coordonnées de B et C en fonction de A, D et R.
On ne connait pas les deux cercles tangents aux axes.
Empiriquement je trouve qu'il y a une infinité de solutions. Il manque une contrainte.
Je tripatouille un peu les équations et je reviens
Résoudre le système suivant avec , , , , , et comme inconnues :
Si on peut trouver en fonction de et , partir de me semble compliqué.
Cela se simplifie puis je bloque:
J'ai remplacé et par et par soucis de cohérence. Et et .
Les solutions sont et . Les seules inconnues restantes sont et . Il "suffit" de résoudre la dernière équation (en x et en y).
Bon , j'ai toujours pas de solution algébrique mais ce système d'équation est vraiment stable. J'ai donc fait un petit programme qui trouve facilement la solution
from sys import float_info
from math import cos, sin, pi
def approx_equal(x, y):
return abs(x - y) <= abs(x + y) * float_info.epsilon
def find_zero(func, x_low, x_high):
""" Find a zero of the given function between x_low and x_high """
y_low, y_high = func(x_low), func(x_high)
if y_low == 0:
return x_low
if y_high == 0:
return x_high
assert y_low * y_high < 0
if y_low > y_high:
x_low, x_high = x_high, x_low
while not approx_equal(x_low, x_high):
x = (x_low + x_high) / 2
y = func(x)
if y > 0:
x_high = x
else:
x_low = x
return (x_low + x_high) / 2
def get_or(u, ux, uy, a, r):
if u == 0:
return 0, r, "Inf"
r1 = ((u * ux - a) ** 2 + (u * uy) ** 2) / (2 * u * uy)
m = r / r1
return m * a + (1 - m) * u * ux, r + (1 - m) * u * uy, r1
def find_solution(alpha, beta, a, d, r):
ux, uy = cos(alpha * pi / 180), sin(alpha * pi / 180)
vx, vy = sin(beta * pi / 180), cos(beta * pi / 180)
u_max = find_zero(lambda u: get_or(u, ux, uy, a, r)[1], 0, a)
v_max = find_zero(lambda v: get_or(v, vy, vx, d, r)[1], 0, d)
u, v = u_max / 2, v_max / 2
or_u = get_or(u, ux, uy, a, r)
# or_v has x and y inverted
or_v = get_or(v, vy, vx, d, r)
print(or_u, or_v)
while not (approx_equal(or_u[0], or_v[1]) and approx_equal(or_u[1], or_v[0])):
u = find_zero(lambda u: get_or(u, ux, uy, a, r)[0] - or_v[1], 0, u_max)
or_u = get_or(u, ux, uy, a, r)
v = find_zero(lambda v: get_or(v, vy, vx, d, r)[0] - or_u[1], 0, v_max)
or_v = get_or(v, vy, vx, d, r)
print(f"r1: {or_u[2]}")
print(f"r2: {or_v[2]}")
print(f"B: {(u * ux, u * uy)}")
print(f"C: {(v * vx, v * vy)}")
print(f"Or: {or_u[:2]}")
print(f"Or: {or_v[:2][::-1]}")
if __name__ == "__main__":
find_solution(alpha=7.75, beta=4.75, a=1.5273, d=1.4000, r=1.2)
Et voici les paramètres pour les rayons demandés:
R u v r1 r2 Bx By Cx Cy Orx Ory
1.8 1.237667 1.497052 3.202183 2.829469 1.224072 0.182939 0.065300 1.495627 1.823759 1.880106
1.6 1.108793 1.281722 2.850718 2.407341 1.097319 0.159104 0.072664 1.279661 1.624369 1.669805
1.4 0.977761 1.085009 2.500102 2.043260 0.968245 0.136078 0.075686 1.082366 1.423828 1.459877
1.2 0.844617 0.902706 2.149235 1.712221 0.836902 0.113897 0.074751 0.899606 1.222362 1.250304
1.0 0.709363 0.732059 1.797306 1.402043 0.703294 0.092590 0.070165 0.728689 1.020120 1.041074
0.8 0.571975 0.571123 1.443649 1.105991 0.567402 0.072183 0.062176 0.567728 0.817202 0.832183
0.6 0.432409 0.418455 1.087666 0.819997 0.429186 0.052697 0.050997 0.415336 0.613682 0.623627
0.4 0.290606 0.272941 0.728786 0.541436 0.288592 0.034157 0.036806 0.270448 0.409615 0.415410
moi aussi je dis bravo ...
mais il me reste toujours un pb : je ne comprends pas quel est exactement le pb :
on ne sait pas exactement quelle est la situation de départ
on ne sait pas exactement ce qui est demandé et ce qu'on veut faire
Bonjour,
J'ai voulu vérifier les valeurs données par LittleFox, mais j'ai des résultats différents (Sauf pour R=1.2):
R=1,8 r2= Point(0,939178562135782 , 1,40000000000028) distance OB=0,960550540607582
B: Point(0,951776773404587 , 0,12953113397586)
C: Point(0,0840602140518238 , 1,01163292834565)
R=1,4 r2= Point(1,32702311070757 , 1,40000000000075) distance OB=0,894688150527691
B: Point(0,88651597715403 , 0,120649529403536)
C: Point(0,0788807106575253 , 0,949299561184338)
R=1,2 r2= Point(1,71220639980783 , 1,39999999999948) distance OB=0,844623994031827
B: Point(0,836909111800839 , 0,113898331326699)
C: Point(0,0747516225997495 , 0,899607545878387)
R=1 r2= Point(2,39807406945592 , 1,39999999999977) distance OB=0,776270692206745
B: Point(0,769180156048572 , 0,104680824988306)
C: Point(0,0689066220273828 , 0,829265171523263)
J'ai créé une fonction qui suit un tracé sur GeoGebra et mes calculs suivent bien GeoGebra.
Je n'ai qu'un seul ajustement à faire (par dichotomie) pour chaque valeur de R (les points A et D restant fixes)
J'ai placé les valeurs pour R=1.8 de LittleFox sur GeoGebra et les poins B et C ne sont pas sur les droites d'angles 7.75° et 4.75°
Le point C a même une ordonnée supérieure à 1.4
Mais c'est peut-être moi qui n'a pas les bonnes initialisations.
Pourtant j'ai bien celles de la dernière ligne du programme de Littlefox qui est :
find_solution(alpha=7.75, beta=4.75, a=1.5273, d=1.4000, r=1.2)
Bonjour,
J'ai pris les points A et D fixes, je vais refaire avec
A = R*7/5.5 et D = R*7/6
De même Alpha et bêta sont fionction de R dans l'énoncé, ce qui n'apparaît pas dans le programme de LittleFox.
Pas de problème dans ma programmation objets.
Vuillez m'excuser LittleFox, votre tableau est OK
je n'avais pas utilisé les angles et les points A et D de l'énoncé
qui dépendent de R "programmé"
Pas de soucis
Voici la version du programme qui calcule le tableau. Il y a le calcul des paramètres alpha, beta, a et d en plus. Et une petite modification de la fonction approx_equal car en voulant être trop précis, mon programme se bloquait juste à côté de la solution (environ 10^-16) pour certains R.
Bonjour à tous,
Tout d'abord, merci d'avoir pris le temps de me répondre
Je viens de vérifier vos résultats LittleFox et ils sont exacts.
Je suis impressionné par votre réflexion, je pense pas que j'y serrais arrivée seul.
Je vais analyser votre programme pour bien comprendre le cheminement .
Pour expliquer mieux mon problème, il s'agit d'une programmation sur une machine-outil, la géométrie correspond à un profil que mon outil doit suivre afin d'obtenir un rayon parfait. En effet, en programmant simplement un rayon, la machine n'arrive pas à reproduire celui-ci exactement. Après plusieurs essais, je suis arrivé à obtenir cette géométrie, qui évolue suivant le rayon programmé afin d'obtenir le résultat voulue.
Le but de trouver une formule et de pouvoir la rentrer dans la machine, afin que l'opérateur n'est qu'à saisir le rayon voulut, en découle les coordonnées du point en laquelle la machine doit passer. (Pas facile à expliquer je reconnais)
Le probleme que je vous pose est ''simplement'' de déterminer les coordonnées de chaque point de mon rayon, il va falloir que je trouve ensuite les coordonnée de l'outil qui suit cette géométrie.
@kilianf12: Content que ça te plaise. J'ai passé pas mal de temps sur ce problème. Surtout à chercher une formule algébrique de la solution. Sans succès
J'avais compris que c'était pour une machine outils mais c'est quand même des paramètres bizarres
J'ai fait une petite activité Géogébra pour aider à comprendre :
Si on connait A, B et R alors on peut calculer la position de Or. Géométriquement c'est facile, algébriquement un peu moins mais faisable. C'est la fonction get_or(u, ux, uy, a, r).
Comme B ne dépend que d'un paramètre u, le reste étant fixé on obtient une courbe paramétrique pour Or. C'est la courbe bleue du bas.
On peut faire la même chose avec D,C et R. Ça donne la courbe bleue du haut. J'utilise la même fonction en ayant échangé x et y.
La solution est l'intersection de ces deux courbes paramétriques. Je cherche d'abord l'intersection avec les axes pour avoir les domaines des paramètres u et v.
Ensuite on peut voir que près de la solution, la courbe du bas "Or(u)" est presque horizontale alors que celle du haut "Or(v)" est presque verticale.
Je cherche donc la valeur de u telle que l'abscisse de Or(u) soit égale à l'abscisse de Or(v). Puis je cherche v tel que l'ordonnée de Or(v) soit égale à l'ordonnée de Or(u). Et je recommence jusqu'à ce que les deux Or soit assez proches.
Pour trouver ces intersections, j'utilise la fonction find_zero(func, x_low, x_high) qui est une implémentation de la méthode de dichotomie:
Une fois u et v trouvés, il est facile de calculer tout ce qui est demandé: B, C mais aussi r1, r2 et Or.
Bonjour,
Pour remercier LittleFox des pistes et solution qu'il a ouvertes
Mais j'ai eu du mal à suivre son programme :
N'étant qu'un programmeur amateur tardif en Python, le "lambda" m'était inconnu
et je serais heureux d'un tutoriel qui le détaillerait mieux que j'ai pu le comprendre.
J'avais une solution en VB.net qui place directement l'ordonnée de O2 = d
je l'ai retranscrit en Python et cela me parait plus facile à suivre et donne
le même tableau que le programme de LittleFox avec une seule dichotomie sans problème.
from math import cos, sin, tan, pi, sqrt
def trouve_o2():
global u,ux,uy,r1,r2,orx,ory,cx,cy
ux, uy = u*cos(alpha*pi/180), u*sin(alpha*pi/180)
r1 = ((ux-a)**2 + uy**2)/(2*uy)
m = r/r1
orx, ory = m*a + (1-m)*ux, r + (1-m)*uy # va placer le point C provisoire
mc = 1/tan(beta*pi/180) # droite (OC) : équation y=x*tan(beta)soit y=mc*x
# pour trouver C :résoudre x²(1+mc²)-2x*(orx+mc*ory)+(orx²+ory²-r²) = 0
bp, cp = (orx + mc*ory)/(1 + mc**2), (orx**2 + ory**2 - r**2)/(1 + mc**2)
if bp**2 - cp < 0:
print("Pas de solution")
cx = bp - sqrt(bp**2 - cp)
cy = cx*mc # puis O2 : intersection de (COr) et de la médiatrice du segment [CD]
pc, pm = (ory-cy) / (orx-cx), cx /(d-cy) # pentes de (COr) et de la médiatrice
r2 = (2*cx*pc - cx*pm - cy + d)/(2*pc-2*pm) # Calcul de o2 avec le support de Xcas
o2y = (cx*pc*pm + cy*pc - 2*cy*pm + d*pc)/(2*pc-2*pm)
return o2y
print(" R u v r1 r2 Bx By Cx Cy Orx Ory")
for i in range(18, 2,-2): # Boucle principale
r = i / 10
alpha = 6.25 + r*1.25
beta = 9.25 - r*3.75
a = r*7/5.5
d = r*7/6
u, pas = a/4, a/200 # Chercher umin et umax
y=trouve_o2()-d
while y < 0.0:
u+=pas
y=trouve_o2()-d
umin, umax = u-pas, u # La dichotomie peut commencer
u = (umin + umax)/2
y = trouve_o2()-d
while abs(y)> 10**(-12):
if y>0:umax = u
else:umin = u
u = (umin + umax)/2
y = trouve_o2()-d
print("{0} {1:.6f} {2:.6f} {3:.6f} {4:.6f} {5:.6f} {6:.6f} {7:.6f} {8:.6f} {9:.6f} {10:.6f}"
.format(r,u,sqrt(cx**2+cy**2),r1,r2,ux,uy,cx,cy,orx,ory))
En tant que programmeur aguerrit, ton global pique mes yeux
Mais c'est une bonne idée, c'est plus efficace de n'avoir qu'une seule dichotomie à faire même si les calculs sont plus lourds.
Moi j'aime bien la symétrie de ma solution .
Ton programme consiste à trouvé l'intersection entre le lieu de O2 et l'horizontale passant par D dans le graphe ci-dessous, si j'ai bien compris
Re bonjour,
Oui, mon programme positionne O2 en ordonnée O2y = d
Pourquoi les variables globales seraient--elles interdites dans un programme isolé ?
Effectivement il vaut mieux protéger ces variables en les passant en paramêtres et en return, mais je l'ai fait par "facilité".
C'est l'utilisation du "lamda" qui m'est apparu compliquée, conjuguée avec la double dichotomie....
A mon niveau je donne plutôt la priorité à la simplicité....
Tutoriel pour vos "lambdas" ? . Mais votre solution est brillante !
@vham
Les globals ne sont pas du tout interdit surtout dans un petit programme comme ceux-ci. Dans un plus grand projet, ça devient plus difficile d'être sûr de ne pas modifier une variable utilisée à un autre point du programme, dans une autre fonction.
Donner les variables d'entrée et de sortie d'une fonction aide aussi à la compréhension de celle-ci.
J'avoue, j'ai été un peu radin sur les commentaires j'ai essayé d'être le plus explicite possible dans mes noms de fonction et de variable. Mais quelques commentaires en plus n'aurait pas fait de mal.
Pour les lambda: les lambda sont juste des fonctions sans nom. J'ai d'un côté une fonction générique qui trouve le zéro d'une fonction de vers par dichotomie (find_zero) et de l'autre côté une fonction qui donne un point Or en fonction de u, ux, uy, a et r (get_or). Je cherche le u tel que l'abscisse de Or soit égale à une constante. Je construit donc une fonction qui prend u en argument et renvoie l'abscisse moins la constante et j'en cherche le zéro.
lambda u: get_or(u, ux, uy, a, r)[0] - or_v[1]
Bonjour,
Merci Merci Merci LIttleFox, je n'avais jamais vu l'utilisation de fonctions imbriquées et je vais réviser la portée des variables ...et ce truc tordu qui va me sortir du VB.net
Bonjour,
J'ai des idées pour donner les points B, C, O1, O2, Or en fonction de R choisi réel entre 0.4 et 1.8 avec un programme tout simple exploitant un tableau de valeurs arrangées à partir des valeurs déjà calculées par LittleFox.
À plus tard car j'ai une autre activité en cours...
Bonjour,
Mon idée était de calculer les droites (BOr) et (COr) sous la forme y=mx+y0
pour les "r programmé" de 0.4 à 1.8
de tracer les courbes fonction de r pour las 2 pentes et les 2 ordonnées yo
afin d'interpoler et d'avoir les droites
fonction de "r programmé" comme les droites (OB) et (OC) données dans l'énoncé.
La mise en œuvre ne serait alors plus que des intersections de droites.
Mais je suis saturé par ce problème, à moins que ce soit vraiment utile à kilianf12
Encore merci à Littlefox pour ce qu'il m'a fait découvrir en programmation Python.
Vous devez être membre accéder à ce service...
Pas encore inscrit ?
1 compte par personne, multi-compte interdit !
Ou identifiez-vous :