2017-07-06 6 views
0

J'ai des angles qui forment un tour complet dans un tableau x, de -90 à 270 par ex. (Il peut être défini autrement, comme de 0 à 360 ou -180 à 180) avec l'étape 1 ou autre.Les valeurs complètes de virage x angle sont mappées à demi-tour à l'aide de la fonction asin, comment les mettre en miroir?

asin La fonction est valide uniquement entre -90 et +90.

Ainsi, les angles < -90 ou> 90 seraient "mappés" entre ces valeurs.

E.g. y = some_asin_func (over_sin (x)) se retrouvera dans une valeur y toujours comprise entre -90 et +90. Donc, y est coincé entre -90 et +90.

Je dois récupérer auquel x-entrée est y liée, car il est encore ambigu: par exemple, la fonction plus (x) donnera les mêmes valeurs pour yx = 120 et x = 60 ou x = -47 et x = 223. Ce qui n'est pas ce que je veux.
Mettez une autre façon; J'ai besoin de y faire un tour complet comme x fait, allant de x commence à se termine.

Une image sera mieux:

original_curves1

Ici, x est comprise entre -90 (gauche) à 270 (à droite du graphique).
La partie valide de la courbe est comprise entre x=-90 et x=+90 (moitié gauche du graphique).
Toutes les autres valeurs sont similaires à celles de y = 90 ou y=-90.
Pour x=180 par exemple, j'ai obtenu y=0 et il devrait être y=180.
Pour x=270, j'ai y=-90 mais il devrait être y=270, donc +360.

Voici un exemple de code:

A = 50 # you can make this value vary to have different curves like in the images, when A=0 -> shape is triangle-like, when A=90-> shape is square-like. 
x = np.linspace(-90,270,int(1e3)) 
u = np.sin(math.pi*A/180)*np.cos(math.pi*x/180) 
v = 180*(np.arcsin(u))/math.pi 
y = 180*np.arcsin(np.sin(math.pi*x/180)/np.cos(math.pi*v/180))/math.pi 
plt.plot(x,y) 
plt.grid(True) 

Encore une fois, la première moitié gauche du graphique est tout à fait correct. La moitié droite est également correct dans son comportement, mais en finale, ici, il doit être mis en miroir autour d'un axe horizontal à la position y=+90 quand x>90, comme ceci:

wanted_curves1

C'est, il est comme la fonction se reflète environ y = -90 et y = + 90 pour yx est hors de l'intervalle [-90, + 90] et que lorsque x où est hors de l'intervalle [-90, + 90].

Je veux un miroir en dehors de la validité [-90, + 90] Plage:
à propos y=-90y est inférieur à -90
sur les y=+90y est supérieure à +90

Et bien sûr, modulo chaque tour complet.

Voici un autre exemple où x est comprise entre -180 et 180 et le comportement souhaité:

Or:

original_curves2

recherchés:

wanted_curves2

Je premier testé quelque chose de simple en ce moment:

A = 50 
x = np.linspace(-180,180,int(1e3)) 
u = np.sin(math.pi*A/180)*np.cos(math.pi*x/180) 
v = 180*(np.arcsin(u))/math.pi 
y = 180*np.arcsin(np.sin(math.pi*x/180)/np.cos(math.pi*v/180))/math.pi 
for i,j in np.ndenumerate(x): 
    xval = (j-180)%180-180 
    if (xval < -90): 
     y[i] = y[i]-val 
    elif (xval > 90): 
     y[i] = y[i]+val 

plt.plot(x,y); 
plt.grid(True) 
plt.show() 

qui ne fonctionne tout mais je pense pas que l'idée de fond est là ...
je pense que ce peut être un certain genre de truc modulo mais ne peut pas comprendre.

+0

Je ne suis pas sûr de comprendre ce que vous essayez de faire. Voulez-vous des paires de x-y sur un cercle d'unité en fonction de l'angle en coordonnées polaires? –

+0

On pourrait voir Backgroud comme si je voulais récupérer une étoile azimutale (mesurée sur un plan horizontal) en fonction de son angle sur le plan équatorial sur lequel elle se déplace, par rapport au nord. J'ai donc besoin de récupérer les valeurs 0-360 y-entières en fonction de la fonction sur les autres valeurs x 0-360. –

+0

Ai-je bien compris le cœur de la question: vous voulez définir une courbe comme dans le second graphique? – kazemakase

Répondre

0

Merci @Thomas Kühn, il semble bien sauf que je voulait limiter la fonction dans un même tour par rapport aux valeurs y. De toute façon, c'est seulement de l'esthétique.

Voici ce que j'ai trouvé à mes côtés.Il est peut-être pas parfait, mais cela fonctionne:

A = 50 
u = np.sin(math.pi*A/180)*np.cos(math.pi*x/180) 
v = 180*(np.arcsin(u))/math.pi 
y = 180*np.arcsin(np.sin(math.pi*x/180)/np.cos(math.pi*v/180))/math.pi 
for i,j in np.ndenumerate(x): 
    val = (j-180)%360-180 
    if (val < -90): 
     y[i] = -180-y[i] 
    elif (val > 90): 
     y[i] = 180-y[i] 

Voici quelques résultats attendus:

Results1

Gamme de -180 à +180

Results1

plage de 0 à +360

Results3

échelonnent de -720 à +720

Results4

Range -360 à 360 avec des A différentes valeurs.

Chose amusante, c'est que cela me rappelle aussi certains schémas électroniques.
Les phénomènes périodiques sont partout!

+0

s'il vous plaît voir la modification de ma réponse –

1

Voici une solution qui fixe la périodicité de « force brute » la fonction cos en calculant une offset et une correction sign sur la base de la valeur x. Je suis sûr qu'il y a quelque chose de mieux là-bas, mais j'aurais presque besoin d'un dessin avec les angles et les distances impliqués.

from matplotlib import pyplot as plt 
import numpy as np 

fig, ax = plt.subplots(1,1, figsize=(4,4)) 

x = np.linspace(-540,540,1000) 
sign = np.sign(np.cos(np.pi*x/180)) 
offset = ((x-90)//180)*180 

for A in range(1,91,9): 

    u = np.sin(np.pi*A/180)*np.cos(np.pi*x/180) 
    v = 180*(np.arcsin(u))/np.pi 
    y = 180*np.arcsin(np.sin(np.pi*x/180)/np.cos(np.pi*v/180))/np.pi 
    y = sign*y + offset 

    ax.plot(x,y) 

ax.grid(True) 
plt.show() 

Le résultat de l'intervalle [-540, 540] ressemble à ceci:

result of the given code

Notez que vous pouvez obtenir pi aussi de numpy, de sorte que vous n'avez pas besoin d'importer math - je modifier la code en conséquence.

EDIT: Apparemment, j'ai d'abord mal compris la sortie désirée de l'OP. Si le calcul de offset est légèrement modifiée, le résultat est tel que demandé:

from matplotlib import pyplot as plt 
import numpy as np 

fig, ax = plt.subplots(1,1, figsize=(4,4)) 

x = np.linspace(-720,720,1000) 
sign = np.sign(np.cos(np.pi*x/180)) 
offset = ((x-90)//180 +1)*180 - ((x-180)//360+1)*360 

for A in range(1,91,9): 

    u = np.sin(np.pi*A/180)*np.cos(np.pi*x/180) 
    v = 180*(np.arcsin(u))/np.pi 
    y = 180*np.arcsin(np.sin(np.pi*x/180)/np.cos(np.pi*v/180))/np.pi 
    y = sign*y + offset 

    ax.plot(x,y) 

ax.grid(True) 
plt.show() 

Le résultat ressemble maintenant à ceci:

updated figure