Example #1
0
 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")]
Example #2
0
 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")]
Example #3
0
  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
Example #4
0
  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
Example #5
0
 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')]
Example #6
0
 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)]
Example #7
0
 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'))
Example #8
0
 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))
Example #9
0
 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)]
Example #10
0
 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))
Example #11
0
  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))
Example #12
0
  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))
Example #13
0
  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)]
Example #14
0
  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)]
Example #15
0
  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))
Example #16
0
  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))
Example #17
0
  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))
Example #18
0
  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))
Example #19
0
  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))
Example #20
0
  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))
Example #21
0
 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))
Example #22
0
 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))