def _draw_wedge( self, coords): """returns the polygon item""" x1, y1, x2, y2 = coords # main item x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, self.wedge_width/2.0) xa, ya, xb, yb = geometry.find_parallel( x1, y1, x2, y2, self.line_width/2.0) return [self._create_polygon_with_transform( (xa, ya, x0, y0, 2*x2-x0, 2*y2-y0, 2*x1-xa, 2*y1-ya), width=0, fill=self.line_color, joinstyle="miter")]
def _draw_hatch( self, coords): """returns list items""" if not hasattr( self, 'equithick'): self.equithick = 0 x1, y1, x2, y2 = coords # main item x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, self.wedge_width/2.0) xa, ya, xb, yb = geometry.find_parallel( x1, y1, x2, y2, self.line_width/2.0) d = math.sqrt( (x1-x2)**2 + (y1-y2)**2) # length of the bond if d == 0: return [] # to prevent division by zero dx1 = (x0 - xa)/d dy1 = (y0 - ya)/d dx2 = (2*x2 -x0 -2*x1 +xa)/d dy2 = (2*y2 -y0 -2*y1 +ya)/d # params for equithick dx = (x2 - x1)/d dy = (y2 - y1)/d ddx = x - x1 ddy = y - y1 # we have to decide if the first line should be at the position of the first atom draw_start = 0 # is index not boolean if not self.atom1.show and self.atom1.occupied_valency > 1: draw_start = 1 draw_end = 1 # is added to index not boolean if not self.atom2.show and self.atom2.occupied_valency > 1: draw_end = 0 # djust the step length step_size = 2*(self.line_width+1) ns = round( d / step_size) or 1 step_size = d / ns # now we finally draw items = [] for i in range( draw_start, int( round( d/ step_size)) +draw_end): if self.equithick: coords = [x1 + i*step_size*dx + ddx, y1 + i*step_size*dy + ddy, x1 + i*step_size*dx - ddx, y1 + i*step_size*dy - ddy] if coords[0] == coords[2] and coords[1] == coords[3]: if (dx1+dx2) > (dy1+dy2): coords[0] += 1 else: coords[1] += 1 else: # real wedge, not "equithick" coords = [xa+dx1*i*step_size, ya+dy1*i*step_size, 2*x1-xa+dx2*i*step_size, 2*y1-ya+dy2*i*step_size] if coords[0] == coords[2] and coords[1] == coords[3]: if (dx1+dx2) > (dy1+dy2): coords[0] += 1 else: coords[1] += 1 items.append( self._create_line_with_transform( coords, width=self.line_width, fill=self.line_color)) return items
def draw( self): if self.items: warnings.warn( "draw called on already drawn mark!", UserWarning, 2) self.delete() s = round( self.size / 2) x1, y1, x2, y2 = self.x, self.y, self.atom.x, self.atom.y # one end x, y = geometry.find_parallel( x1, y1, x2, y2, s)[0:2] # and the other x0, y0 = geometry.find_parallel( x1, y1, x2, y2, -s)[0:2] self.items = [self.paper.create_line( x, y, x0, y0, fill=self.line_color, width=self.line_width, tags='mark')]
def _draw_second_line( self, coords): my_x1, my_y1 = self.atom1.get_xy() my_x2, my_y2 = self.atom2.get_xy() my_coords = (my_x1,my_y1,my_x2,my_y2) x, y, x0, y0 = coords # shortening of the second bond dx = x-x0 dy = y-y0 if self.center: _k = 0 else: _k = (1-self.double_length_ratio)/2 x, y, x0, y0 = x-_k*dx, y-_k*dy, x0+_k*dx, y0+_k*dy # shift according to the bonds arround side = geometry.on_which_side_is_point( my_coords, (x,y)) for atom in (self.atom1,self.atom2): second_atom = atom is self.atom1 and self.atom2 or self.atom1 neighs = [n for n in atom.neighbors if geometry.on_which_side_is_point( my_coords, n.get_xy())==side and n is not second_atom] for n in neighs: dist2 = _k*geometry.point_distance(*my_coords)*geometry.on_which_side_is_point((atom.x, atom.y, n.x, n.y), (second_atom.x, second_atom.y)) xn1, yn1, xn2, yn2 = geometry.find_parallel( atom.x, atom.y, n.x, n.y, dist2) xp,yp,parallel,online = geometry.intersection_of_two_lines( x,y,x0,y0,xn1,yn1,xn2,yn2) if not parallel: if not geometry.is_point_beween_points_of_line( (x,y,x0,y0),(xp,yp)): # only shorten the line - do not elongate it continue if geometry.point_distance( atom.x,atom.y,x,y) < geometry.point_distance( atom.x,atom.y,x0,y0): x,y = xp, yp else: x0,y0 = xp, yp else: # parallel pass return [self._create_line_with_transform( (x, y, x0, y0), width=self.line_width, fill=self.line_color)]
def draw( self): if self.items: warnings.warn( "draw called on already drawn mark!", UserWarning, 2) self.delete() s = round( self.size / 2) x1, y1, x2, y2 = self.x, self.y, self.atom.x, self.atom.y x, y = geometry.find_parallel( x1, y1, x2, y2, s*1.5)[0:2] # one circle self.items = [self.paper.create_oval( x-s, y-s, x+s, y+s, fill=self.line_color, outline=self.line_color, tags='mark')] # and the second on the other side x, y = geometry.find_parallel( x1, y1, x2, y2, -s*1.5)[0:2] self.items.append( self.paper.create_oval( x-s, y-s, x+s, y+s, fill=self.line_color, outline=self.line_color, tags='mark'))
def _draw_a2( self): if self.center is None or self.bond_width is None: self._decide_distance_and_center() d = self.bond_width # double if self.center: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where self.paper.itemconfig( self.item, fill='') d = int( round( d/3)) else: where = self._draw_a1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # gray magic (not black, but not so white :) _second_draw_method = (self.simple_double and not self.center) and self._draw_second_line or self._draw_adder self.second = _second_draw_method( (x,y,x0,y0)) if self.center: self.third = _second_draw_method( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_a2( self): if self.center == None or self.bond_width == None: self._decide_distance_and_center() d = self.bond_width # double if self.center: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where self.paper.itemconfig( self.item, fill='') d = int( round( d/3)) else: where = self._draw_a1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # gray magic (not black, but not so white :) _second_draw_method = (self.simple_double and not self.center) and self._draw_second_line or self._draw_adder self.second = _second_draw_method( (x,y,x0,y0)) if self.center: self.third = _second_draw_method( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_a3( self): where = self._draw_a1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.bond_width == None: self._decide_distance_and_center() d = self.bond_width x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # gray magic (not black, but not so white :) _second_draw_method = (self.simple_double and not self.center) and self._draw_second_line or self._draw_adder self.second = _second_draw_method( (x,y,x0,y0)) self.third = _second_draw_method( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_a3( self): where = self._draw_a1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.bond_width is None: self._decide_distance_and_center() d = self.bond_width x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # gray magic (not black, but not so white :) _second_draw_method = (self.simple_double and not self.center) and self._draw_second_line or self._draw_adder self.second = _second_draw_method( (x,y,x0,y0)) self.third = _second_draw_method( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_adder( self, coords): """returns list items""" if not hasattr( self, 'equithick'): self.equithick = 0 x1, y1, x2, y2 = coords # main item x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, self.wedge_width/2.0) d = math.sqrt( (x1-x2)**2 + (y1-y2)**2) # length of the bond if self.equithick: step_size = 1.8*self.line_width else: step_size = self.line_width+1 dx1 = (x0 - x1)/d dy1 = (y0 - y1)/d dx2 = (2*x2 -x0 -x1)/d dy2 = (2*y2 -y0 -y1)/d # params for equithick dx = (x2 - x1)/d dy = (y2 - y1)/d ddx = x - x1 ddy = y - y1 coords2 = [] coords2.extend((x1, y1)) for i in range( 0, int( round( d/ step_size))+1): if self.equithick: coords = [x1+dx*i*step_size+ddx, y1+dy*i*step_size+ddy, x1+dx*i*step_size-ddx, y1+dy*i*step_size-ddy] else: coords = [x1+dx1*i*step_size, y1+dy1*i*step_size, x1+dx2*i*step_size, y1+dy2*i*step_size] if (coords[0] == coords[2] and coords[1] == coords[3]) and not self.equithick: if (dx1+dx2) > (dy1+dy2): coords[0] += 1 else: coords[1] += 1 if i % 2: coords2.extend((coords[0], coords[1])) else: coords2.extend((coords[2], coords[3])) coords2.extend((x2, y2)) if self.equithick: return [self._create_line_with_transform( coords2, width=self.line_width, fill=self.line_color, smooth=1)] else: return [self._create_line_with_transform( coords2, width=self.line_width, fill=self.line_color)]
def _draw_n2( self): where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.center == None or self.bond_width == None: self._decide_distance_and_center() d = self.bond_width # double if self.center: self.paper.itemconfig( self.item, fill='') # d = int( round( d/3)) #MB# d = round(d*.4) #MB#+ x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) self.second = self._draw_second_line( [x, y, x0, y0]) if self.center: self.third = self._draw_second_line( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_n2( self): where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.center is None or self.bond_width is None: self._decide_distance_and_center() d = self.bond_width # double if self.center: self.paper.itemconfig( self.item, fill='') # d = int( round( d/3)) #MB# d = round(d*.4) #MB#+ x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) self.second = self._draw_second_line( [x, y, x0, y0]) if self.center: self.third = self._draw_second_line( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_n3( self): where = self._draw_n1() if not where: # the bond is too short to draw it return None if self.atom1.show and self.atom2.show: # both atoms are shown - we don't want round edges at the ends of the central bond # and we don't want to apply shortening of other lines self.paper.itemconfig( self.item, capstyle="butt") _k = 0 else: _k = (1-self.double_length_ratio)/2 x1, y1, x2, y2 = where if self.bond_width == None: self._decide_distance_and_center() d = self.bond_width x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d*3/4) self.second = self._draw_second_line( [x, y, x0, y0]) self.third = self._draw_second_line( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_n3( self): where = self._draw_n1() if not where: # the bond is too short to draw it return None if self.atom1.show and self.atom2.show: # both atoms are shown - we don't want round edges at the ends of the central bond # and we don't want to apply shortening of other lines self.paper.itemconfig( self.item, capstyle="butt") _k = 0 else: _k = (1-self.double_length_ratio)/2 x1, y1, x2, y2 = where if self.bond_width is None: self._decide_distance_and_center() d = self.bond_width x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d*3/4) self.second = self._draw_second_line( [x, y, x0, y0]) self.third = self._draw_second_line( (2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_o2( self): if self.center is None or self.bond_width is None: self._decide_distance_and_center() d = self.bond_width # double if self.center: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where self.paper.itemconfig( self.item, fill='') d = int( round( d/3)) else: if self.simple_double: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where else: where = self._draw_o1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # shortening of the second bond dx = x-x0 dy = y-y0 if self.center: _k = 0 else: _k = (1-self.double_length_ratio)/2 self.second = self._draw_dotted(( x-_k*dx, y-_k*dy, x0+_k*dx, y0+_k*dy)) if self.center: self.third = self._draw_dotted(( 2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_o2( self): if self.center == None or self.bond_width == None: self._decide_distance_and_center() d = self.bond_width # double if self.center: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where self.paper.itemconfig( self.item, fill='') d = int( round( d/3)) else: if self.simple_double: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where else: where = self._draw_o1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d) # shortening of the second bond dx = x-x0 dy = y-y0 if self.center: _k = 0 else: _k = (1-self.double_length_ratio)/2 self.second = self._draw_dotted(( x-_k*dx, y-_k*dy, x0+_k*dx, y0+_k*dy)) if self.center: self.third = self._draw_dotted(( 2*x1-x, 2*y1-y, 2*x2-x0, 2*y2-y0))
def _draw_o3( self): if self.simple_double: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where else: where = self._draw_o1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.bond_width == None: self._decide_distance_and_center() d = self.bond_width # we don't want to shorten the bonds (yet) _k = (1-self.double_length_ratio)/2 _k = 0 x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d*3/4) dx = x-x0 dy = y-y0 self.second = self._draw_dotted(( x-_k*dx, y-_k*dy, x0+_k*dx, y0+_k*dy)) self.third = self._draw_dotted(( 2*x1-x-_k*dx, 2*y1-y-_k*dy, 2*x2-x0+_k*dx, 2*y2-y0+_k*dy))
def _draw_o3( self): if self.simple_double: where = self._draw_n1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where else: where = self._draw_o1() if not where: # the bond is too short to draw it return None x1, y1, x2, y2 = where if self.bond_width is None: self._decide_distance_and_center() d = self.bond_width # we don't want to shorten the bonds (yet) _k = (1-self.double_length_ratio)/2 _k = 0 x, y, x0, y0 = geometry.find_parallel( x1, y1, x2, y2, d*3/4) dx = x-x0 dy = y-y0 self.second = self._draw_dotted(( x-_k*dx, y-_k*dy, x0+_k*dx, y0+_k*dy)) self.third = self._draw_dotted(( 2*x1-x-_k*dx, 2*y1-y-_k*dy, 2*x2-x0+_k*dx, 2*y2-y0+_k*dy))