def graph2vpoints( graph: Graph, pos: Dict[int, Tuple[float, float]], cus: Dict[str, int], same: Dict[int, int] ) -> List[VPoint]: """Change NetworkX graph into VPoints.""" same_r = {} for k, v in same.items(): if v in same_r: same_r[v].append(k) else: same_r[v] = [k] tmp_list = [] ev = dict(edges_view(graph)) for i, e in ev.items(): if i in same: # Do not connect to anyone! continue e = set(e) if i in same_r: for j in same_r[i]: e.update(set(ev[j])) link = ", ".join((str(l) if l else 'ground') for l in e) x, y = pos[i] tmp_list.append(VPoint.r_joint(link, x, y)) for name in sorted(cus): link = str(cus[name]) if cus[name] else 'ground' x, y = pos[int(name.replace('P', ''))] tmp_list.append(VPoint.r_joint(link, x, y)) return tmp_list
def graph2vpoints(G: Graph, pos: Dict[int, Tuple[float, float]], cus: Dict[str, int], same: Dict[int, int]) -> Tuple[VPoint]: """Change Networkx graph into VPoints.""" same_r = {} for k, v in same.items(): if v in same_r: same_r[v].append(k) else: same_r[v] = [k] tmp_list = [] ev = dict(edges_view(G)) for i, e in ev.items(): if i in same: #Do not connect to anyone! link = '' else: e = set(e) if i in same_r: for j in same_r[i]: e.update(set(ev[j])) link = ", ".join((str(l) if (l != 0) else 'ground') for l in e) tmp_list.append(VPoint(link, 0, 0., 'Green', *pos[i])) for name in sorted(cus): tmp_list.append( VPoint( str(cus[name]) if (cus[name] != 0) else 'ground', 0, 0., 'Green', *pos[int(name.replace('P', ''))])) return tmp_list
def __draw_point(self, i: int, vpoint: VPoint): """Draw a point.""" if vpoint.type in {VJoint.P, VJoint.RP}: pen = QPen(QColor(*vpoint.color)) pen.setWidth(2) # Draw slot point and pin point. for j, (cx, cy) in enumerate(vpoint.c): if not vpoint.links: grounded = False else: grounded = vpoint.links[j] == 'ground' # Slot point. if j == 0 or vpoint.type == VJoint.P: pen.setColor(Qt.black if self.monochrome else QColor( *vpoint.color)) self.painter.setPen(pen) cp = QPointF(cx, -cy) * self.zoom jr = self.joint_size * (2 if j == 0 else 1) rp = QPointF(jr, -jr) self.painter.drawRect(QRectF(cp + rp, cp - rp)) if self.show_point_mark: pen.setColor(Qt.darkGray) self.painter.setPen(pen) text = f"[Point{i}]" if self.show_dimension: text += f":({cx:.02f}, {cy:.02f})" self.painter.drawText(cp + rp, text) else: self.draw_point(i, cx, cy, grounded, vpoint.color) # Slider line pen.setColor(QColor(*vpoint.color).darker()) self.painter.setPen(pen) qline_m = QLineF( QPointF(vpoint.c[1][0], -vpoint.c[1][1]) * self.zoom, QPointF(vpoint.c[0][0], -vpoint.c[0][1]) * self.zoom) nv = qline_m.normalVector() nv.setLength(self.joint_size) nv.setPoints(nv.p2(), nv.p1()) qline_1 = nv.normalVector() qline_1.setLength(qline_m.length()) self.painter.drawLine(qline_1) nv.setLength(nv.length() * 2) nv.setPoints(nv.p2(), nv.p1()) qline_2 = nv.normalVector() qline_2.setLength(qline_m.length()) qline_2.setAngle(qline_2.angle() + 180) self.painter.drawLine(qline_2) else: self.draw_point(i, vpoint.cx, vpoint.cy, vpoint.grounded(), vpoint.color) # For selects function. if self.select_mode == SelectMode.Joint and (i in self.selections): pen = QPen(QColor(161, 16, 239)) pen.setWidth(3) self.painter.setPen(pen) self.painter.drawRect(vpoint.cx * self.zoom - 12, vpoint.cy * -self.zoom - 12, 24, 24)
def __drawPoint(self, i: int, vpoint: VPoint): """Draw a point.""" if vpoint.type == 1 or vpoint.type == 2: #Draw slider silder_points = vpoint.c for j, (cx, cy) in enumerate(silder_points): if vpoint.type == 1: if j == 0: self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) else: pen = QPen(vpoint.color) pen.setWidth(2) self.painter.setPen(pen) r = 5 self.painter.drawRect( QRectF( QPointF(cx * self.zoom + r, cy * -self.zoom + r), QPointF(cx * self.zoom - r, cy * -self.zoom - r))) elif vpoint.type == 2: if j == 0: self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) else: #Turn off point mark. showPointMark = self.showPointMark self.showPointMark = False self._BaseCanvas__drawPoint( i, cx, cy, vpoint.links[j] == 'ground', vpoint.color) self.showPointMark = showPointMark pen = QPen(vpoint.color.darker()) pen.setWidth(2) self.painter.setPen(pen) x_all = tuple(cx for cx, cy in silder_points) if x_all: p_left = silder_points[x_all.index(min(x_all))] p_right = silder_points[x_all.index(max(x_all))] if p_left == p_right: y_all = tuple(cy for cx, cy in silder_points) p_left = silder_points[y_all.index(min(y_all))] p_right = silder_points[y_all.index(max(y_all))] self.painter.drawLine( QPointF(p_left[0] * self.zoom, p_left[1] * -self.zoom), QPointF(p_right[0] * self.zoom, p_right[1] * -self.zoom)) else: self._BaseCanvas__drawPoint(i, vpoint.cx, vpoint.cy, vpoint.grounded(), vpoint.color) #For selects function. if i in self.pointsSelection: pen = QPen(QColor(161, 16, 239)) pen.setWidth(3) self.painter.setPen(pen) self.painter.drawRect(vpoint.cx * self.zoom - 12, vpoint.cy * -self.zoom - 12, 24, 24)
def data(self) -> Iterator[VPoint]: """Yield the digitization of all table data.""" for row in range(self.rowCount()): links = self.item(row, 1).text() color = self.item(row, 3).text() x = float(self.item(row, 4).text()) y = float(self.item(row, 5).text()) # p_type = (type: str, angle: float) p_type = self.item(row, 2).text().split(':') if p_type[0] == 'R': type_int = 0 angle = 0. else: angle = float(p_type[1]) type_int = 1 if p_type[0] == 'P' else 2 vpoint = VPoint(links, type_int, angle, color, x, y, color_qt) vpoint.move(*self.currentPosition(row)) yield vpoint
def item_data(self, row: int) -> VPoint: """Return data of VPoint.""" links = self.item(row, 1).text() color = self.item(row, 3).text() x = float(self.item(row, 4).text()) y = float(self.item(row, 5).text()) # p_type = (type: str, angle: float) p_type = self.item(row, 2).text().split(':') if p_type[0] == 'R': j_type = VJoint.R angle = 0. else: angle = float(p_type[1]) j_type = VJoint.P if p_type[0] == 'P' else VJoint.RP vpoint = VPoint([ link for link in links.replace(" ", '').split(',') if link ], j_type, angle, color, x, y, color_rgb) vpoint.move(*self.current_position(row)) return vpoint
def data(self) -> VPoint: """Yield the digitization of all table data.""" for row in range(self.rowCount()): Links = self.item(row, 1).text() color = self.item(row, 3).text() x = float(self.item(row, 4).text()) y = float(self.item(row, 5).text()) ''' Type = (type:str, angle:float) ''' Type = self.item(row, 2).text().split(':') if Type[0] == 'R': Type = 0 angle = 0. elif Type[0] == 'P' or Type[0] == 'RP': angle = float(Type[1]) Type = {'P': 1, 'RP': 2}[Type[0]] vpoint = VPoint(Links, Type, angle, color, x, y, colorQt) vpoint.move(*self.currentPosition(row)) yield vpoint
def test_solving(self): """Test triangular formula solving. + Jansen's linkage (Single). """ vpoints = [ VPoint("ground, link_1", 0, 0., 'Green', 0., 0.), VPoint("link_1, link_2, link_4", 0, 0., 'Green', 9.61, 11.52), VPoint("ground, link_3, link_5", 0, 0., 'Blue', -38.0, -7.8), VPoint("link_2, link_3", 0, 0., 'Green', -35.24, 33.61), VPoint("link_3, link_6", 0, 0., 'Green', -77.75, -2.54), VPoint("link_4, link_5, link_7", 0, 0., 'Green', -20.1, -42.79), VPoint("link_6, link_7", 0, 0., 'Green', -56.05, -35.42), VPoint("link_7", 0, 0., 'Green', -22.22, -91.74), ] x, y = expr_solving(vpoints_configure(vpoints, [(0, 1)]), {n: 'P{}'.format(n) for n in range(len(vpoints))}, vpoints, [0.])[-1] self.assertTrue(isclose(x, -43.17005515543241)) self.assertTrue(isclose(y, -91.75322590542523))