def _click(self, e): x = e.x y = e.y self.angle = int( round(180 * geometry.clockwise_angle_from_east(x - 30, y - 30) / math.pi)) self.counter.setentry(self.angle)
def _create_arrow( self, shape, start, to, color): """creates an arrow with 'shape' pointing from 'start' to 'to' filled with 'color' and returns x, y - where the to should be to not to overlay the arrow""" a, b, c = map( float, shape.split()) points = [a,0, a-b,c, 0,0, a-b,-c] ang = geometry.clockwise_angle_from_east( to[0]-start[0], to[1]-start[1]) tr = transform.transform() tr.set_move( -a, 0) tr.set_rotation( ang) tr.set_move( to[0], to[1]) points = tr.transform_xy_flat_list( points) points = self.transformer.transform_xy_flat_list( points) points = self._flat_list_to_list_of_tuples( points) self.canvas.drawPolygon( points, edgeColor=color, edgeWidth=0, fillColor=color, closed=1) return points[2]
def find_least_crowded_place_around_atom( self, a, range=10): atms = a.neighbors x, y = a.get_xy() if not atms: # single atom molecule if a.show_hydrogens and a.pos == "center-first": return x -range, y else: return x +range, y angles = [geometry.clockwise_angle_from_east( at.x-a.x, at.y-a.y) for at in atms] angles.append( 2*pi + min( angles)) angles = sorted(angles, reverse=True) diffs = misc.list_difference( angles) i = diffs.index( max( diffs)) angle = (angles[i] +angles[i+1]) / 2 return x +range*cos( angle), y +range*sin( angle)
def find_least_crowded_place_around_atom(self, a, range=10): atms = a.neighbors x, y = a.get_xy() if not atms: # single atom molecule if a.show_hydrogens and a.pos == "center-first": return x - range, y else: return x + range, y angles = [ geometry.clockwise_angle_from_east(at.x - a.x, at.y - a.y) for at in atms ] angles.append(2 * pi + min(angles)) angles = sorted(angles, reverse=True) diffs = misc.list_difference(angles) i = diffs.index(max(diffs)) angle = (angles[i] + angles[i + 1]) / 2 return x + range * cos(angle), y + range * sin(angle)
def _create_arrow(self, shape, start, to, color): """creates an arrow with 'shape' pointing from 'start' to 'to' filled with 'color' and returns x, y - where the to should be to not to overlay the arrow""" a, b, c = map(float, shape.split()) points = [a, 0, a - b, c, 0, 0, a - b, -c] ang = geometry.clockwise_angle_from_east(to[0] - start[0], to[1] - start[1]) tr = transform.transform() tr.set_move(-a, 0) tr.set_rotation(ang) tr.set_move(to[0], to[1]) points = tr.transform_xy_flat_list(points) points = self.transformer.transform_xy_flat_list(points) points = self._flat_list_to_list_of_tuples(points) self.canvas.drawPolygon(points, edgeColor=color, edgeWidth=0, fillColor=color, closed=1) return points[2]
def _create_arrow( self, shape, start, to, color): """creates an arrow with 'shape' pointing from 'start' to 'to' filled with 'color' and returns x, y - where the to should be to not to overlay the arrow""" a, b, c = map( float, shape.split()) points = [a,0, a-b,c, 0,0, a-b,-c] ang = geometry.clockwise_angle_from_east( to[0]-start[0], to[1]-start[1]) tr = transform.transform() tr.set_move( -a, 0) tr.set_rotation( ang) tr.set_move( to[0], to[1]) points = tr.transform_xy_flat_list( points) points = self.transformer.transform_xy_flat_list( points) points = self._flat_list_to_list_of_tuples( points) self.context.set_line_join( cairo.LINE_JOIN_MITER) self._create_cairo_path( points, closed=True) is_visible = self.set_cairo_color( color) if is_visible: self.context.fill() return points[1]
def _create_arrow(self, shape, start, to, color): """creates an arrow with 'shape' pointing from 'start' to 'to' filled with 'color' and returns x, y - where the to should be to not to overlay the arrow""" a, b, c = map(float, shape.split()) points = [a, 0, a - b, c, 0, 0, a - b, -c] ang = geometry.clockwise_angle_from_east(to[0] - start[0], to[1] - start[1]) tr = transform.transform() tr.set_move(-a, 0) tr.set_rotation(ang) tr.set_move(to[0], to[1]) points = tr.transform_xy_flat_list(points) points = self.transformer.transform_xy_flat_list(points) points = self._flat_list_to_list_of_tuples(points) self.context.set_line_join(cairo.LINE_JOIN_MITER) self._create_cairo_path(points, closed=True) is_visible = self.set_cairo_color(color) if is_visible: self.context.fill() return points[1]
def find_place_for_mark( self, mark, resolution=30): """resolution says if the angles should be somehow 'rounded', it is given in degrees; see geometry.point_on_circle for a similar thing""" mark_name, mark_class = self._mark_to_name_and_class( mark) # deal with marks centered if mark_class.meta__mark_positioning == 'atom': return self.x, self.y # deal with statically positioned marks if mark_class.meta__mark_positioning == 'righttop': bbox = self.bbox() return bbox[2]+2, bbox[1] # deal with marks in linear_form if self.is_part_of_linear_fragment(): if mark_name == "atom_number": bbox = self.bbox() return int( self.x-0.5*self.font_size), bbox[1]-2 if not self.show: dist = 5 + round( mark_class.standard_size / 2) else: dist = 0.75*self.font_size + round( mark_class.standard_size / 2) atms = self.get_neighbors() x, y = self.get_xy() # special cases if not atms: # single atom molecule if self.show_hydrogens and self.pos == "center-first": return x -dist, y-3 else: return x +dist, y-3 # normal case coords = [(a.x,a.y) for a in atms] # we have to take marks into account [coords.append( (m.x, m.y)) for m in self.marks] # hydrogen positioning is also important if self.show_hydrogens and self.show: if self.pos == 'center-last': coords.append( (x-10,y)) else: coords.append( (x+10,y)) # now we can compare the angles angles = [geometry.clockwise_angle_from_east( x1-x, y1-y) for x1,y1 in coords] angles.append( 2*pi + min( angles)) angles.sort() angles.reverse() diffs = misc.list_difference( angles) i = diffs.index( max( diffs)) angle = (angles[i] +angles[i+1]) / 2 # we calculate the distance here again as it is anisotropic (depends on direction) bbox = list( misc.normalize_coords( self.bbox())) x0, y0 = geometry.point_on_circle( x, y, 500, direction=(cos(angle), sin( angle)), resolution=resolution) x1, y1 = geometry.intersection_of_line_and_rect( (x,y,x0,y0), bbox, round_edges=0) dist = geometry.point_distance( x, y, x1, y1) + round( mark_class.standard_size / 2) # // retx, rety = geometry.point_on_circle( x, y, dist, direction=(cos(angle), sin( angle)), resolution=resolution) # in visible text x,y are not on the center, therefore we compensate for it # if self.show: # y -= 0.166 * self.font_size return retx, rety
def _click( self, e): x = e.x y = e.y self.angle = int( round( 180*geometry.clockwise_angle_from_east( x - 30, y - 30) / math.pi)) self.counter.setentry( self.angle)
def find_place_for_mark(self, mark, resolution=30): """resolution says if the angles should be somehow 'rounded', it is given in degrees; see geometry.point_on_circle for a similar thing""" mark_name, mark_class = self._mark_to_name_and_class(mark) # deal with marks centered if mark_class.meta__mark_positioning == 'atom': return self.x, self.y # deal with statically positioned marks if mark_class.meta__mark_positioning == 'righttop': bbox = self.bbox() return bbox[2] + 2, bbox[1] # deal with marks in linear_form if self.is_part_of_linear_fragment(): if mark_name == "atom_number": bbox = self.bbox() return int(self.x - 0.5 * self.font_size), bbox[1] - 2 if not self.show: dist = 5 + round(mark_class.standard_size / 2) else: dist = 0.75 * self.font_size + round(mark_class.standard_size / 2) atms = self.get_neighbors() x, y = self.get_xy() # special cases if not atms: # single atom molecule if self.show_hydrogens and self.pos == "center-first": return x - dist, y - 3 else: return x + dist, y - 3 # normal case coords = [(a.x, a.y) for a in atms] # we have to take marks into account [coords.append((m.x, m.y)) for m in self.marks] # hydrogen positioning is also important if self.show_hydrogens and self.show: if self.pos == 'center-last': coords.append((x - 10, y)) else: coords.append((x + 10, y)) # now we can compare the angles angles = [ geometry.clockwise_angle_from_east(x1 - x, y1 - y) for x1, y1 in coords ] angles.append(2 * pi + min(angles)) angles.sort() angles.reverse() diffs = misc.list_difference(angles) i = diffs.index(max(diffs)) angle = (angles[i] + angles[i + 1]) / 2 # we calculate the distance here again as it is anisotropic (depends on direction) bbox = list(misc.normalize_coords(self.bbox())) x0, y0 = geometry.point_on_circle(x, y, 500, direction=(cos(angle), sin(angle)), resolution=resolution) x1, y1 = geometry.intersection_of_line_and_rect((x, y, x0, y0), bbox, round_edges=0) dist = geometry.point_distance(x, y, x1, y1) + round( mark_class.standard_size / 2) # // retx, rety = geometry.point_on_circle(x, y, dist, direction=(cos(angle), sin(angle)), resolution=resolution) # in visible text x,y are not on the center, therefore we compensate for it # if self.show: # y -= 0.166 * self.font_size return retx, rety