Double Helix Generation Algorithm

I am trying to find a good algorithm to create a righthand DNA string representation with primary and secondary grooves using a dash symbol for an arbitrary number of characters.

This is what I now have, using 776 # 's:

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

but the spiral is not perfectly aligned when I manually try to repeat the spiral by copying / pasting.

A solution that has the same width as the example above but also has cruciform basepair pairs (as in this image or in the scarf in the figure below) is also acceptable.

scarf pattern

+6
source share
5 answers

The key to this is recognizing that you can think of each strand on a spiral as a combination of sine waves — one for the periodic part and one for the “depth” on the page. Once you have parameterized the problem this way, you can control every aspect of your spiral. The example below uses * and # to show different strands to illustrate this point. If you choose wavelengths that are not commensurate with integer values, you will get less than optimal results - but now you can play with the inputs to find what you consider the most aesthetically pleasing presentation.

 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) 

These values ​​give:

  ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ****** ######### ######### ######### **** ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ###### ********* ********* ********* #### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ********* ######### ****** ######### ######### 
+6
source

This should give you a decent start:

 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() 

as indicated, produces

  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 

(Xs and Os should just show that this is indeed a right spiral).

+2
source

How about this:

 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) 

It does not use a certain number of hashes for output. Perhaps this was one of your requirements, I don’t know ...

It should cause a repeating pattern if step is an integer math.pi

+2
source

Here is my approach. This is probably not significantly different from anyone else, but I wrote it, so here it is:

The upper half is the configuration. The lower half is an action.

 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)) 

Conclusion:

  ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ######## ########## ##### ########## # ########## ########## # ########## ##### ########## ######## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ######## ########## ##### ########## # ########## ########## # ########## ##### ########## ######### ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## 
+2
source
  ########## #### ########## ######## ########## ########### ########## ########## ########## ########## ########## ######### ########## ######### ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########### ########## ######### ########## ##### ########## # ########## ########## ### ########## ####### ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ########## ####### ########## #### ######### ######### # 

.,.

Unfortunately, I wanted this to be the result of my answer. But I have to explain: when you make changes to tessellation, you need to work with a basic repeating block (and if you change the way it is tessellated, you will have to change other parts of it, but you don’t). I cut my pattern into what I thought looked like a repeating block, and then copied it once; when I made the change to the bottom, I made the same change at the top.

<deep thoughts> Sometimes the simplest solutions are found without too much thought. </ deep thoughts>

However, you can definitely execute the posterization algorithm on the DNA image, turning it into a raster image. (You can do this with a copyrighted image.) If you cannot use the same symbol, you can also use the ascii art generator, from which you can find dozens on the Internet and in open source software source code through some google searches. This, however, is not within the scope of the StackOverflow frequently asked questions, so I will not dwell on this in detail, except that the link to this computer science article on ascii-art vector conversion is: http: //www.cse.cuhk. edu.hk/~ttwong/papers/asciiart/asciiart.pdf

+1
source

Source: https://habr.com/ru/post/913942/


All Articles