使用双曲正切在Python中创建螺旋结构

时间:2016-03-18 23:11:30

标签: python arrays coordinate-transformation spiral

我试图在Python的2D数组中创建一个螺旋结构,如星系的旋臂。我做的第一个简单的方法就是使用一个简单的对数螺旋函数,在图像中定义:log spiral function

xy值由

创建
x,y=meshgrid(arange(0,M=400,1), arange(0,N=400,1))

MN是数组的维度。半径坐标很简单,就像最后一张图像的等式一样,

r=(abs(x-gal_center[1])**(2.0)+((abs(y-gal_center[0]))/(q))**(2.0))**(0.5)

创建f(r)的轮廓亮度,并绘制

plt.imshow((abs(galaxy_model))**0.2)

给我一​​个共同的螺旋结构,就像一个螺旋星系。

另一种方法是使用另一个函数hyperbolic tangent。 在最后一张图像的等式中,除非r,如前所述,所有其他参数都是可调数。

对于此功能,我在2D阵列中制作螺旋结构时遇到问题。我不知道,如果我需要使用双曲正切来在数组中进行坐标变换,或者使用矩阵/数组失真来创建螺旋结构。我试过了,但我做不到。

如何使用上面的定义来制作此spira / image? 谢谢你的帮助!

有关该主题的更多信息,请参阅参考资料:

  1. Peng,Y。Chien等;银河系图像的详细结构分解,2002
  2. Peng,Y。Chien等;银河系图像的详细分解。 II。超越轴对称模型,2009
  3. Peng,Y。Chien,Galfit User's Manual,2003
  4. Rowe,Barnaby等; GALSIM:模块化星系图像模拟工具包,2015
  5. 编辑:

    我使用的代码如下:

    from __future__ import division
    import numpy as np
    from numpy import*
    import matplotlib.pyplot as pyplot
    import scipy as sp
    from scipy import*
    import pylab as pl
    from pylab import*
    import math 
    from math import*
    import pyfits as pf
    from pyfits import*
    
    def exponential_profile(Io,ro,r):
        Iexp=0.5*Io*np.exp(-r/ro)
        return Iexp
    
    def sersic_profile(Io,ro,r,n):
        Iser=Io*np.exp(-(r/ro)**(1/n))
        return Iser
    
    def galaxy_model1(q,c,gal_center,Io,ro,n,M,N,xi,p,n1,n2,s1,s2,k):
        x,y=meshgrid(arange(-M/2,M/2,1), arange(-N/2,N/2,1))
        r=(abs(x-0*gal_center[1])**(c+2.0)+((abs(y-0*gal_center[0]))/(q))**(c+2.0))**(1.0/(c+2.0))
        power=2.0
        fr=(30-xi*np.log(1.0+r**power)+(1.0/p)*np.cos(n1*arctan2(x,y)+k*np.log(s1+r**power))+(1.0/p)*np.cos(n2*arctan2(x,y)+k*np.log(s2+r**power))  )
        I_exp=exponential_profile(Io,ro,r)
        I_ser=sersic_profile(Io,ro,r,n)
        galaxy_model_1=0.1*I_exp+0.1*I_ser+0.5*fr
        return galaxy_model_1
    
    def galaxy_model2(q,c,Cb,rout,rin,Oout,a,M,N,Io,ro,n):
        gal_center=(M/2,N/2)
        x,y=meshgrid(arange(0,M,1), arange(0,N,1))
        r=(abs(x-0*gal_center[1])**(c+2.0)+((abs(y-0*gal_center[0]))/(q))**(c+2.0))**(1.0/(c+2.0))
        A=2*Cb/(abs(Oout)+Cb)-1.00001
        B=(2-np.arctanh(A))*((rout)/(rout-rin))
        T=0.5*(np.tanh(B*(r/rout-1)+2)+1)
        Or=Oout*T*(0.5*(r/rout+1))**a
        I_exp=exponential_profile(Io,ro,r)
        I_ser=sersic_profile(Io,ro,r,n)
        galaxy_model_2=0.1*I_exp+0.1*I_ser+0.5*Or
        return galaxy_model_2
    galaxy_model_1=galaxy_model1(q,c,(M/2,N/2),Io,ro,n,M,N,xi,p,n1,n2,s1,s2,k)
    galaxy_model_2=galaxy_model2(q,c,Cb,rout,rin,Oout,a,M,N,Io,ro,n)
    fig=plt.figure()
    ax1=fig.add_subplot(121)
    ax1.imshow((abs(galaxy_model_1))**0.2)
    pf.writeto('gal_1.fits', galaxy_model_1,  clobber=1)  
    ax2=fig.add_subplot(122, axisbg='white')
    ax2.imshow((abs(galaxy_model_2))**0.2)
    plt.show()
    

    一组参数可以是:

    M=400
    N=400
    q=0.8
    c=0.0
    Io=100.0
    ro=10.0
    n=3.0
    xi=2.0
    p=1.7
    n1=3.0
    n2=3.0
    s1=0.05
    s2=0.5
    k=3.0
    Cb=0.23
    rout=100.0
    rin=10.0
    Oout=pi/2
    a=0.0
    

1 个答案:

答案 0 :(得分:2)

我不确定这是完全正确的,但我认为它很接近,并产生类似于论文的结果:

def galaxy_model2(q,c,Cb,rout,rin,Oout,a,M,N,Io,ro,n):
    gal_center=(0,0)
    x,y=meshgrid(arange(-M/2,M/2,1), arange(-N/2,N/2,1))
    r=(abs(x-gal_center[1])**(c+2.0)+((abs(y-gal_center[0]))/(q))**(c+2.0))**(1.0/(c+2.0))
    A=2*Cb/(abs(Oout)+Cb)-1.00001
    B=(2-np.arctanh(A))*((rout)/(rout-rin))
    T=0.5*(np.tanh(B*(r/rout-1)+2)+1)
    Or=Oout*T*(0.5*(r/rout+1))**a
    Or=30-np.log(1.0+r**2.0)+(2.0/p)*np.cos(n2*arctan2(x,y)+k*Or)
    I_exp=exponential_profile(Io,ro,r)
    I_ser=sersic_profile(Io,ro,r,n)
    #galaxy_model_2=0.5*Or
    return Or

唯一的变化是我使用

Or=30-np.log(1.0+r**2.0)+(2.0/p)*np.cos(n2*arctan2(x,y)+k*Or)

创建一个星系图。

np.cos(n1*arctan2(x,y))

创建此图:

enter image description here

我通过添加k*Or

来旋转它

使用n2 = 3我得到:

enter image description here