graphics/GraphicCommons.py
changeset 1768 691083b5682a
parent 1767 c74815729afd
child 1777 c46ec818bdd7
equal deleted inserted replaced
1767:c74815729afd 1768:691083b5682a
  1103     # Make a clone of the connector
  1103     # Make a clone of the connector
  1104     def Clone(self, parent=None):
  1104     def Clone(self, parent=None):
  1105         if parent is None:
  1105         if parent is None:
  1106             parent = self.ParentBlock
  1106             parent = self.ParentBlock
  1107         return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]),
  1107         return Connector(parent, self.Name, self.Type, wx.Point(self.Pos[0], self.Pos[1]),
  1108                 self.Direction, self.Negated)
  1108                          self.Direction, self.Negated)
  1109 
  1109 
  1110     # Returns the connector parent block
  1110     # Returns the connector parent block
  1111     def GetParentBlock(self):
  1111     def GetParentBlock(self):
  1112         return self.ParentBlock
  1112         return self.ParentBlock
  1113 
  1113 
  1932                 y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE
  1932                 y2 = self.Points[i + 1].y + self.Segments[-1][1] * CONNECTOR_SIZE
  1933             else:
  1933             else:
  1934                 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
  1934                 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
  1935             # Calculate a rectangle around the segment
  1935             # Calculate a rectangle around the segment
  1936             rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
  1936             rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
  1937                 abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
  1937                            abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
  1938             test |= rect.InsideXY(pt.x, pt.y)
  1938             test |= rect.InsideXY(pt.x, pt.y)
  1939         return test
  1939         return test
  1940 
  1940 
  1941     # Returns the wire start or end point if the point given is on one of them
  1941     # Returns the wire start or end point if the point given is on one of them
  1942     def TestPoint(self, pt):
  1942     def TestPoint(self, pt):
  1943         # Test the wire start point
  1943         # Test the wire start point
  1944         rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE,
  1944         rect = wx.Rect(self.Points[0].x - ANCHOR_DISTANCE, self.Points[0].y - ANCHOR_DISTANCE,
  1945             2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
  1945                        2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
  1946         if rect.InsideXY(pt.x, pt.y):
  1946         if rect.InsideXY(pt.x, pt.y):
  1947             return 0
  1947             return 0
  1948         # Test the wire end point
  1948         # Test the wire end point
  1949         if len(self.Points) > 1:
  1949         if len(self.Points) > 1:
  1950             rect = wx.Rect(self.Points[-1].x - ANCHOR_DISTANCE, self.Points[-1].y - ANCHOR_DISTANCE,
  1950             rect = wx.Rect(self.Points[-1].x - ANCHOR_DISTANCE, self.Points[-1].y - ANCHOR_DISTANCE,
  1951                 2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
  1951                            2 * ANCHOR_DISTANCE, 2 * ANCHOR_DISTANCE)
  1952             if rect.InsideXY(pt.x, pt.y):
  1952             if rect.InsideXY(pt.x, pt.y):
  1953                 return -1
  1953                 return -1
  1954         return None
  1954         return None
  1955 
  1955 
  1956     # Returns the wire segment if the point given is on it
  1956     # Returns the wire segment if the point given is on it
  1960             if all or 0 < i < len(self.Segments) - 1:
  1960             if all or 0 < i < len(self.Segments) - 1:
  1961                 x1, y1 = self.Points[i].x, self.Points[i].y
  1961                 x1, y1 = self.Points[i].x, self.Points[i].y
  1962                 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
  1962                 x2, y2 = self.Points[i + 1].x, self.Points[i + 1].y
  1963                 # Calculate a rectangle around the segment
  1963                 # Calculate a rectangle around the segment
  1964                 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
  1964                 rect = wx.Rect(min(x1, x2) - ANCHOR_DISTANCE, min(y1, y2) - ANCHOR_DISTANCE,
  1965                     abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
  1965                                abs(x1 - x2) + 2 * ANCHOR_DISTANCE, abs(y1 - y2) + 2 * ANCHOR_DISTANCE)
  1966                 if rect.InsideXY(pt.x, pt.y):
  1966                 if rect.InsideXY(pt.x, pt.y):
  1967                     return i, self.Segments[i]
  1967                     return i, self.Segments[i]
  1968         return None
  1968         return None
  1969 
  1969 
  1970     # Define the wire points
  1970     # Define the wire points
  1974             # Calculate the start and end directions
  1974             # Calculate the start and end directions
  1975             self.StartPoint = [None, vector(self.Points[0], self.Points[1])]
  1975             self.StartPoint = [None, vector(self.Points[0], self.Points[1])]
  1976             self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])]
  1976             self.EndPoint = [None, vector(self.Points[-1], self.Points[-2])]
  1977             # Calculate the start and end points
  1977             # Calculate the start and end points
  1978             self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0],
  1978             self.StartPoint[0] = wx.Point(self.Points[0].x + CONNECTOR_SIZE * self.StartPoint[1][0],
  1979                 self.Points[0].y + CONNECTOR_SIZE * self.StartPoint[1][1])
  1979                                           self.Points[0].y + CONNECTOR_SIZE * self.StartPoint[1][1])
  1980             self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0],
  1980             self.EndPoint[0] = wx.Point(self.Points[-1].x + CONNECTOR_SIZE * self.EndPoint[1][0],
  1981                 self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1])
  1981                                         self.Points[-1].y + CONNECTOR_SIZE * self.EndPoint[1][1])
  1982             self.Points[0] = self.StartPoint[0]
  1982             self.Points[0] = self.StartPoint[0]
  1983             self.Points[-1] = self.EndPoint[0]
  1983             self.Points[-1] = self.EndPoint[0]
  1984             # Calculate the segments directions
  1984             # Calculate the segments directions
  1985             self.Segments = []
  1985             self.Segments = []
  1986             i = 0
  1986             i = 0
  2011 
  2011 
  2012     # Returns a list of the position of all wire points
  2012     # Returns a list of the position of all wire points
  2013     def GetPoints(self, invert=False):
  2013     def GetPoints(self, invert=False):
  2014         points = self.VerifyPoints()
  2014         points = self.VerifyPoints()
  2015         points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0],
  2015         points[0] = wx.Point(points[0].x - CONNECTOR_SIZE * self.StartPoint[1][0],
  2016                 points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1])
  2016                              points[0].y - CONNECTOR_SIZE * self.StartPoint[1][1])
  2017         points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0],
  2017         points[-1] = wx.Point(points[-1].x - CONNECTOR_SIZE * self.EndPoint[1][0],
  2018                 points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1])
  2018                               points[-1].y - CONNECTOR_SIZE * self.EndPoint[1][1])
  2019         # An inversion of the list is asked
  2019         # An inversion of the list is asked
  2020         if invert:
  2020         if invert:
  2021             points.reverse()
  2021             points.reverse()
  2022         return points
  2022         return points
  2023 
  2023 
  2053     # Update the wire points position by keeping at most possible the current positions
  2053     # Update the wire points position by keeping at most possible the current positions
  2054     def GeneratePoints(self, realpoints=True):
  2054     def GeneratePoints(self, realpoints=True):
  2055         i = 0
  2055         i = 0
  2056         # Calculate the start enad end points with the minimum segment size in the right direction
  2056         # Calculate the start enad end points with the minimum segment size in the right direction
  2057         end = wx.Point(self.EndPoint[0].x + self.EndPoint[1][0] * MIN_SEGMENT_SIZE,
  2057         end = wx.Point(self.EndPoint[0].x + self.EndPoint[1][0] * MIN_SEGMENT_SIZE,
  2058             self.EndPoint[0].y + self.EndPoint[1][1] * MIN_SEGMENT_SIZE)
  2058                        self.EndPoint[0].y + self.EndPoint[1][1] * MIN_SEGMENT_SIZE)
  2059         start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE,
  2059         start = wx.Point(self.StartPoint[0].x + self.StartPoint[1][0] * MIN_SEGMENT_SIZE,
  2060             self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE)
  2060                          self.StartPoint[0].y + self.StartPoint[1][1] * MIN_SEGMENT_SIZE)
  2061         # Evaluate the point till it's the last
  2061         # Evaluate the point till it's the last
  2062         while i < len(self.Points) - 1:
  2062         while i < len(self.Points) - 1:
  2063             # The next point is the last
  2063             # The next point is the last
  2064             if i + 1 == len(self.Points) - 1:
  2064             if i + 1 == len(self.Points) - 1:
  2065                 # Calculate the direction from current point to end point
  2065                 # Calculate the direction from current point to end point
  2067                 # The current point is the first
  2067                 # The current point is the first
  2068                 if i == 0:
  2068                 if i == 0:
  2069                     # If the end point is not in the start direction, a point is added
  2069                     # If the end point is not in the start direction, a point is added
  2070                     if v_end != self.Segments[0] or v_end == self.EndPoint[1]:
  2070                     if v_end != self.Segments[0] or v_end == self.EndPoint[1]:
  2071                         self.Points.insert(1, wx.Point(start.x, start.y))
  2071                         self.Points.insert(1, wx.Point(start.x, start.y))
  2072                         self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
  2072                         self.Segments.insert(1, DirectionChoice(
  2073                             self.Segments[0][0]), v_end, self.EndPoint[1]))
  2073                             (self.Segments[0][1],
       
  2074                              self.Segments[0][0]), v_end, self.EndPoint[1]))
  2074                 # The current point is the second
  2075                 # The current point is the second
  2075                 elif i == 1:
  2076                 elif i == 1:
  2076                     # The previous direction and the target direction are mainly opposed, a point is added
  2077                     # The previous direction and the target direction are mainly opposed, a point is added
  2077                     if product(v_end, self.Segments[0]) < 0:
  2078                     if product(v_end, self.Segments[0]) < 0:
  2078                         self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2079                         self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2079                         self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
  2080                         self.Segments.insert(2, DirectionChoice(
  2080                             self.Segments[1][0]), v_end, self.EndPoint[1]))
  2081                             (self.Segments[1][1],
       
  2082                              self.Segments[1][0]), v_end, self.EndPoint[1]))
  2081                     # The previous direction and the end direction are the same or they are
  2083                     # The previous direction and the end direction are the same or they are
  2082                     # perpendiculars and the end direction points towards current segment
  2084                     # perpendiculars and the end direction points towards current segment
  2083                     elif product(self.Segments[0], self.EndPoint[1]) >= 0 and product(self.Segments[1], self.EndPoint[1]) <= 0:
  2085                     elif product(self.Segments[0], self.EndPoint[1]) >= 0 and product(self.Segments[1], self.EndPoint[1]) <= 0:
  2084                         # Current point and end point are aligned
  2086                         # Current point and end point are aligned
  2085                         if self.Segments[0][0] != 0:
  2087                         if self.Segments[0][0] != 0:
  2087                         if self.Segments[0][1] != 0:
  2089                         if self.Segments[0][1] != 0:
  2088                             self.Points[1].y = end.y
  2090                             self.Points[1].y = end.y
  2089                         # If the previous direction and the end direction are the same, a point is added
  2091                         # If the previous direction and the end direction are the same, a point is added
  2090                         if product(self.Segments[0], self.EndPoint[1]) > 0:
  2092                         if product(self.Segments[0], self.EndPoint[1]) > 0:
  2091                             self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2093                             self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2092                             self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
  2094                             self.Segments.insert(2, DirectionChoice(
  2093                                 self.Segments[1][0]), v_end, self.EndPoint[1]))
  2095                                 (self.Segments[1][1],
       
  2096                                  self.Segments[1][0]), v_end, self.EndPoint[1]))
  2094                     else:
  2097                     else:
  2095                         # Current point is positioned in the middle of start point
  2098                         # Current point is positioned in the middle of start point
  2096                         # and end point on the current direction and a point is added
  2099                         # and end point on the current direction and a point is added
  2097                         if self.Segments[0][0] != 0:
  2100                         if self.Segments[0][0] != 0:
  2098                             self.Points[1].x = (end.x + start.x) / 2
  2101                             self.Points[1].x = (end.x + start.x) / 2
  2099                         if self.Segments[0][1] != 0:
  2102                         if self.Segments[0][1] != 0:
  2100                             self.Points[1].y = (end.y + start.y) / 2
  2103                             self.Points[1].y = (end.y + start.y) / 2
  2101                         self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2104                         self.Points.insert(2, wx.Point(self.Points[1].x, self.Points[1].y))
  2102                         self.Segments.insert(2, DirectionChoice((self.Segments[1][1],
  2105                         self.Segments.insert(2, DirectionChoice(
  2103                             self.Segments[1][0]), v_end, self.EndPoint[1]))
  2106                             (self.Segments[1][1],
       
  2107                              self.Segments[1][0]), v_end, self.EndPoint[1]))
  2104                 else:
  2108                 else:
  2105                     # The previous direction and the end direction are perpendiculars
  2109                     # The previous direction and the end direction are perpendiculars
  2106                     if product(self.Segments[i - 1], self.EndPoint[1]) == 0:
  2110                     if product(self.Segments[i - 1], self.EndPoint[1]) == 0:
  2107                         # The target direction and the end direction aren't mainly the same
  2111                         # The target direction and the end direction aren't mainly the same
  2108                         if product(v_end, self.EndPoint[1]) <= 0:
  2112                         if product(v_end, self.EndPoint[1]) <= 0:
  2140                                 if self.Segments[1][0] != 0:
  2144                                 if self.Segments[1][0] != 0:
  2141                                     self.Points[2].x = (self.Points[1].x + end.x) / 2
  2145                                     self.Points[2].x = (self.Points[1].x + end.x) / 2
  2142                                 if self.Segments[1][1] != 0:
  2146                                 if self.Segments[1][1] != 0:
  2143                                     self.Points[2].y = (self.Points[1].y + end.y) / 2
  2147                                     self.Points[2].y = (self.Points[1].y + end.y) / 2
  2144                                 self.Points.insert(3, wx.Point(self.Points[2].x, self.Points[2].y))
  2148                                 self.Points.insert(3, wx.Point(self.Points[2].x, self.Points[2].y))
  2145                                 self.Segments.insert(3, DirectionChoice((self.Segments[2][1],
  2149                                 self.Segments.insert(
  2146                                     self.Segments[2][0]), v_end, self.EndPoint[1]))
  2150                                     3,
       
  2151                                     DirectionChoice((self.Segments[2][1],
       
  2152                                                      self.Segments[2][0]),
       
  2153                                                     v_end,
       
  2154                                                     self.EndPoint[1]))
  2147                     else:
  2155                     else:
  2148                         # Current point is aligned with end point
  2156                         # Current point is aligned with end point
  2149                         if self.Segments[i - 1][0] != 0:
  2157                         if self.Segments[i - 1][0] != 0:
  2150                             self.Points[i].x = end.x
  2158                             self.Points[i].x = end.x
  2151                         if self.Segments[i - 1][1] != 0:
  2159                         if self.Segments[i - 1][1] != 0:
  2161                                 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2
  2169                                 self.Points[i].x = (end.x + self.Points[i - 1].x) / 2
  2162                             if self.Segments[i - 1][1] != 0:
  2170                             if self.Segments[i - 1][1] != 0:
  2163                                 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2
  2171                                 self.Points[i].y = (end.y + self.Points[i - 1].y) / 2
  2164                         # A point is added
  2172                         # A point is added
  2165                         self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y))
  2173                         self.Points.insert(i + 1, wx.Point(self.Points[i].x, self.Points[i].y))
  2166                         self.Segments.insert(i + 1, DirectionChoice((self.Segments[i][1],
  2174                         self.Segments.insert(
  2167                                 self.Segments[i][0]), v_end, self.EndPoint[1]))
  2175                             i + 1,
       
  2176                             DirectionChoice((self.Segments[i][1],
       
  2177                                              self.Segments[i][0]), v_end, self.EndPoint[1]))
  2168             else:
  2178             else:
  2169                 # Current point is the first, and second is not mainly in the first direction
  2179                 # Current point is the first, and second is not mainly in the first direction
  2170                 if i == 0 and product(vector(start, self.Points[1]), self.Segments[0]) < 0:
  2180                 if i == 0 and product(vector(start, self.Points[1]), self.Segments[0]) < 0:
  2171                     # If first and second directions aren't perpendiculars, a point is added
  2181                     # If first and second directions aren't perpendiculars, a point is added
  2172                     if product(self.Segments[0], self.Segments[1]) != 0:
  2182                     if product(self.Segments[0], self.Segments[1]) != 0:
  2173                         self.Points.insert(1, wx.Point(start.x, start.y))
  2183                         self.Points.insert(1, wx.Point(start.x, start.y))
  2174                         self.Segments.insert(1, DirectionChoice((self.Segments[0][1],
  2184                         self.Segments.insert(
  2175                             self.Segments[0][0]), vector(start, self.Points[1]), self.Segments[1]))
  2185                             1,
       
  2186                             DirectionChoice((self.Segments[0][1],
       
  2187                                              self.Segments[0][0]),
       
  2188                                             vector(start, self.Points[1]),
       
  2189                                             self.Segments[1]))
  2176                     else:
  2190                     else:
  2177                         self.Points[1].x, self.Points[1].y = start.x, start.y
  2191                         self.Points[1].x, self.Points[1].y = start.x, start.y
  2178                 else:
  2192                 else:
  2179                     # Next point is aligned with current point
  2193                     # Next point is aligned with current point
  2180                     if self.Segments[i][0] != 0:
  2194                     if self.Segments[i][0] != 0:
  2233                     elif i == len(self.Points) - 1:
  2247                     elif i == len(self.Points) - 1:
  2234                         dir = self.EndPoint[1]
  2248                         dir = self.EndPoint[1]
  2235                     else:
  2249                     else:
  2236                         dir = (0, 0)
  2250                         dir = (0, 0)
  2237                     pointx = max(-dir[0] * MIN_SEGMENT_SIZE, min(int(round(point[0] * width / float(max(lastwidth, 1)))),
  2251                     pointx = max(-dir[0] * MIN_SEGMENT_SIZE, min(int(round(point[0] * width / float(max(lastwidth, 1)))),
  2238                             width - dir[0] * MIN_SEGMENT_SIZE))
  2252                                                                  width - dir[0] * MIN_SEGMENT_SIZE))
  2239                     pointy = max(-dir[1] * MIN_SEGMENT_SIZE, min(int(round(point[1] * height / float(max(lastheight, 1)))),
  2253                     pointy = max(-dir[1] * MIN_SEGMENT_SIZE, min(int(round(point[1] * height / float(max(lastheight, 1)))),
  2240                             height - dir[1] * MIN_SEGMENT_SIZE))
  2254                                                                  height - dir[1] * MIN_SEGMENT_SIZE))
  2241                     self.Points[i] = wx.Point(minx + x + pointx, miny + y + pointy)
  2255                     self.Points[i] = wx.Point(minx + x + pointx, miny + y + pointy)
  2242             self.StartPoint[0] = self.Points[0]
  2256             self.StartPoint[0] = self.Points[0]
  2243             self.EndPoint[0] = self.Points[-1]
  2257             self.EndPoint[0] = self.Points[-1]
  2244             self.GeneratePoints(False)
  2258             self.GeneratePoints(False)
  2245             # Test if the wire position or size have changed
  2259             # Test if the wire position or size have changed
  2267                         dir = self.StartPoint[1]
  2281                         dir = self.StartPoint[1]
  2268                     elif i == len(self.Points) - 1:
  2282                     elif i == len(self.Points) - 1:
  2269                         dir = self.EndPoint[1]
  2283                         dir = self.EndPoint[1]
  2270                     else:
  2284                     else:
  2271                         dir = (0, 0)
  2285                         dir = (0, 0)
  2272                     realpointx = max(-dir[0] * MIN_SEGMENT_SIZE, min(int(round(point[0])),
  2286                     realpointx = max(-dir[0] * MIN_SEGMENT_SIZE,
  2273                             width - dir[0] * MIN_SEGMENT_SIZE))
  2287                                      min(int(round(point[0])),
  2274                     realpointy = max(-dir[1] * MIN_SEGMENT_SIZE, min(int(round(point[1])),
  2288                                          width - dir[0] * MIN_SEGMENT_SIZE))
  2275                             height - dir[1] * MIN_SEGMENT_SIZE))
  2289                     realpointy = max(-dir[1] * MIN_SEGMENT_SIZE,
       
  2290                                      min(int(round(point[1])),
       
  2291                                          height - dir[1] * MIN_SEGMENT_SIZE))
  2276                     self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy)
  2292                     self.Points[i] = wx.Point(minx + x + realpointx, miny + y + realpointy)
  2277             self.StartPoint[0] = self.Points[0]
  2293             self.StartPoint[0] = self.Points[0]
  2278             self.EndPoint[0] = self.Points[-1]
  2294             self.EndPoint[0] = self.Points[-1]
  2279             self.GeneratePoints(False)
  2295             self.GeneratePoints(False)
  2280 
  2296