2012-04-23 115 views
6

我试图想出一个好的算法来创建right handed DNA串用破折号字符,字符任意数量的主要和次要凹槽的表示。双螺旋生成算法

这是我目前拥有,使用776 #的:

#########     ########## 
    #########    ########## 
     #########    ########## 
     #########   ########## 
      ##########  ########## 
      ########## ########## 
       ###### ########## 
       ## ########## 
       ########## # 
       ########## ##### 
      ########## ######### 
      ########## ########## 
     ##########  ########## 
     ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########   ########## 
    ##########  ########## 
    ########### ########## 
     ######### ########## 
     ##### ########## 
      # ########## 
      ########## ### 
     ########## ####### 
     ########## ########## 
    ##########  ########## 
    ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########     ########## 
    ##########     ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########  ########## 
      ########## ########## 
       ####### ########## 
       #### ######### 
        ######### # 
        ########## ### 
       ########### ####### 

但是当我尝试手动通过复制/粘贴重复螺旋螺旋不完全一致。

与上述示例具有相同宽度但也具有底层交叉粘结(如this image或下面的围巾图案)的解决方案也是可以接受的。

scarf pattern

+4

你为什么不张贴到现在为止您编写的代码?它可能会鼓励人们回答。 – user1202136 2012-04-23 14:42:25

+0

上面的例子是手动完成的。但是这种调整是费力和错误的,所以我认为必须有更好,更算法的方法来做到这一点。 – BioGeek 2012-04-23 14:45:22

回答

6

的关键,这个问题是要认识到,你可以代表对耳轮为正弦波的组合每一条链 - 一个用于周期性的部分,以及一个用于“深度”进入页面。一旦你参数的问题,这样一来,你可以控制你的螺旋的各个方面。下面的示例使用*#以显示不同链说明这一点。如果你选择的是不相称的整数值的波长值,你会得到不到最佳的效果 - 但现在你可以输入发挥找到你认为最美观的表示。

from numpy import * 

amp = 10 
length = 100 
wavelength = 20 

omega = (2*pi)/wavelength 
phi = wavelength*(0.5) 
X = arange(1,length) 
Y1 = round_(amp*(sin(omega*X) + 1)) 
Y2 = round_(amp*(sin(omega*X+phi) + 1)) 

offset = phi/2 
Z1 = sin(omega*X + offset) 
Z2 = sin(omega*X + phi + offset) 

T1 = " ######### " 
T2 = " ********* " 
clen = len(T1) 

H = zeros((length,amp*2+clen),dtype='str') 
H[:,:] = " " 

for n,(y1,y2,z1,z2) in enumerate(zip(Y1,Y2,Z1,Z2)): 
    H[n,y1:y1+clen] = list(T1) 
    H[n,y2:y2+clen] = list(T2) 

    # Overwrite if first helix is on top 
    if z1>z2: H[n,y1:y1+clen] = list(T1) 

for line in H: 
    print "".join(line) 

这些值给出:

********* #########   
    *********  #########  
*********   ######### 
*********   ######### 
    *********   ######### 
    *********  ######### 
     ********* ######### 
      ****** #########  
       #########   
      ######### ****  
     ######### ********* 
    #########  ********* 
    #########   ********* 
#########   ********* 
#########   ********* 
#########  *********  
    ######### *********  
    ###### *********   
     *********    
     ********* ####   
    ********* #########   
    *********  #########  
*********   ######### 
*********   ######### 
    *********   ######### 
    *********  ######### 
     ********* ######### 
      ****** #########  
       #########   
+1

在线19上,不清楚哪个线在哪个线上。每一个都出现在另一个之后。 – recursive 2012-04-23 16:30:51

+1

@recursive同意,在z顺序上添加一个简单的偏移量来修复这个问题。他们需要使各自相位的z阶移动半个波长。谢谢! – Hooked 2012-04-23 17:40:53

1
    ########## #### 
       ########## ######## 
      ########## ########### 
      ##########  ########## 
     ##########   ########## 
     ##########   ######### 
    ##########    ######### 
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########   ########## 
    ##########  ########## 
    ########### ########## 
     ######### ########## 
     ##### ########## 
      # ########## 
      ########## ### 
     ########## ####### 
     ########## ########## 
    ##########  ########## 
    ##########   ########## 
    ##########    ########## 
    ##########    ########## 
    ##########     ########## 
    ##########     ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########  ########## 
      ########## ########## 
       ####### ########## 
       #### ######### 
        ######### # 

。 。 。

可悲的是,我想这是总和我的回答。但是,我要说明一下:当您执行变更tesselations,你需要的基本重复单元的工作(如果你修改tesselates的方式,你必须修改它的其他部分,但你没有这样做)。我砍你的模式成什么样我想看起来像一个重复单元,然后复制粘贴一次;当我对底部做出改变时,我对顶部做了同样的改变。

<浓浓的思念>有时候最简单的解决方案,而无需过多的思考中。 < /深层次的想法>

尽管如此,你绝对可以对DNA图像执行后调算法,将其转化为位图。 (你可以做到这一点给你的。版权的图像)如果你不感激使用相同的字符,你也可以使用一个ASCII艺术发生器,其中你可以找到几十个在网络上和开源软件通过一些谷歌搜索。但是,这并不在StackOverflow常见问题解答的范围内,所以我不会详细讨论这方面的细节,除了将此计算机科学论文链接到矢量风格的ASCII艺术转换之外:http://www.cse.cuhk.edu.hk/~ttwong/papers/asciiart/asciiart.pdf

+1

如果不需要通过算法创建,这当然是最简单的方法。 – 2012-04-23 14:54:11

2

这应该给你一个体面的开始:

from math import sin, cos, pi 

class RightHelix(object): 
    def __init__(self, maxima, minima, period, offset): 
     self.mid = 0.5 * (maxima + minima) 
     self.mag = 0.5 * (maxima - minima) 
     self.k = 2.0 * pi/period 
     self.offs = self.k * offset 
    def x(self, t): 
     return self.mid + self.mag * sin(self.k*t - self.offs) 
    def y(self, t): 
     return -self.mag * cos(self.k*t - self.offs) 

def main(): 
    rh = RightHelix(33, 7, 20, -2) 

    for t in range(40): 
     x,y = rh.x(t), rh.y(t) 
     print(' '*int(x-0.5) + ('O','X')[y>0]) 

if __name__=="__main__": 
    main() 

给出,生产

      O 
           O 
           O 
           O 
           X 
           X 
          X 
         X 
        X 
       X 
      X 
     X 
     X 
     X 
     O 
     O 
      O 
       O 
        O 
         O 
          O 
           O 
           O 
           O 
           X 
           X 
          X 
         X 
        X 
       X 
      X 
     X 
     X 
     X 
     O 
     O 
      O 
       O 
        O 
         O 

(X们和OS只是表明它确实是一个右手螺旋)。

2

这个怎么样:

import math 

phaseA = math.pi/1.5 
phaseB = 0 
step = math.pi/20 
width = 30 # screen size 
breadth = 8 # breadth of DNA single string 

x = 0.0 
while True: 
    x += step 
    if x > 30.0: break 
    yA = math.sin(x + phaseA) 
    zA = math.cos(x + phaseA) 
    yB = math.sin(x + phaseB) 
    zB = math.cos(x + phaseB) 
    if zA > zB: # which is in front? 
    yTop, yBottom = yA, yB 
    else: 
    yTop, yBottom = yB, yA 
    # screenify values: 
    yTop = 1 + int((1.0 + yTop) /2.0 * (width-breadth)) 
    yBottom = 1 + int((1.0 + yBottom)/2.0 * (width-breadth)) 
    line = ' ' * yBottom + '#' * breadth + ' ' * (width-yBottom) 
    line = list(line) # make mutable 
    line[yTop-1] = ' ' 
    line[yTop+breadth+1] = ' ' 
    for i in range(breadth): 
    line[yTop+i] = '#' 
    print ''.join(line) 

它不使用散列对输出的具体数量,但。也许这是你们中的一个要求,不知道...

只要step值是math.pi的整数部分,它就会产生重复模式。

2

这是我的方法。这可能与其他人没有本质区别,但是我写了它,所以这里写着:

上半部分是配置。下半部分是行动。

from math import cos, sin, pi 

length = 50 
width = 30 
thickness = 10 
rotation = 0.15 
strands = [0, 2 * pi/3] 
strand_char = "#" 

radius = width/2 
for line in range(length): 
    output = [" "] * (width + thickness + 2) 
    total_rotation = -line * rotation 
    sorted_strands = sorted(strands, key=lambda s: cos(total_rotation + s)) 
    for strand_offset in sorted_strands: 
     pos = int(radius * sin(total_rotation + strand_offset) + radius) 
     output[pos : pos + thickness + 2] = " " + strand_char * thickness + " " 
    print("".join(output)) 

输出:

   ########## ##########  
      ##########  ########## 
      ##########   ########## 
     ##########   ########## 
     ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ##########  
    ##########    ##########  
##########    ##########  
##########    ##########   
##########   ##########   
##########   ##########    
    ##########  ##########    
    ########## ##########     
    ######## ##########     
    ##### ##########      
     # ##########      
     ########## #      
    ########## #####      
    ########## ########     
    ########## ##########     
##########  ##########    
##########   ##########    
##########   ##########   
##########    ##########   
##########    ##########  
    ##########    ##########  
    ##########    ########## 
    ##########    ########## 
    ##########    ########## 
     ##########    ########## 
     ##########   ########## 
      ##########   ########## 
      ##########  ########## 
       ########## ##########  
        ######## ##########  
        ##### ##########  
         # ##########   
         ########## #   
        ########## #####  
       ########## #########  
       ########## ########## 
      ##########  ########## 
      ##########   ########## 
     ##########   ########## 
     ##########    ########## 
    ##########    ########## 
    ##########    ########## 
    ##########    ##########  
+1

请注意,这是一个左手螺旋... – 2012-04-23 16:23:13

+0

感谢您的更正。我已经扭转了代码中的旋转。 – recursive 2012-04-23 16:25:20