コード例 #1
0
ファイル: Curves.py プロジェクト: ChMcg/CG
class Bezier:
    default_points = [
        v2((10, 10)),
        v2((20, 200)),
        v2((500, 10)),
        v2((500, 300))
    ]

    def __init__(self, points: List[v3] = default_points):
        self.points: List[v2] = points
        # print(points)
        self.n = len(points) - 1
        self.point = v2((0, 0))
        self.current_point = self.points[0]
        self.current_index = 0
        self.spline_points: List[v2] = []
        self.calculate()

    def calculate(self):
        x = [point.x for point in self.points]
        y = [point.y for point in self.points]
        n = self.n
        self.spline_points.clear()
        for t in linspace(0, 1, 50):
            tmp_x = sum([self.N(i, n, t) * x[i] for i in range(0, n + 1)])
            tmp_y = sum([self.N(i, n, t) * y[i] for i in range(0, n + 1)])
            self.spline_points.append(v2((tmp_x, tmp_y)))

    def N(self, i: int, n: int, t: float):
        res = ( factorial(n) )/( factorial(i)*factorial(n-i) ) \
            * t**(i) * (1-t)**(n-i)
        return res

    def set_current_index(self, index):
        self.current_index = index
コード例 #2
0
 def move_point(self, x, y):
     self.curve.current_point = v2((x, y))
     ci = self.curve.current_index
     if ci == -1:
         return
     self.curve.points[ci] = v2((x, y))
     self.curve.calculate()
     self.repaint()
コード例 #3
0
 def temp_highlight(self, painter: QtGui.QPainter):
     for i, line in enumerate(self.lines):
         if i < self.limit:
             Line(line.A, v2([self.poly.x_r_max, line.A.y])).draw(painter, self.center)
             Line(line.B, v2([self.poly.x_r_max, line.B.y])).draw(painter, self.center)
     for key, point in self.poly.cache.items():
         painter.drawEllipse(
             point.to_QPoint() + self.center,
             2,2
         )
コード例 #4
0
 def add_point(self):
     last = self.curve.points[-1]
     points = self.curve.points[:-1]
     points.extend([v2((500, 500)), last])
     self.curve = Bezier(points)
     self.curve.calculate()
     self.repaint()
コード例 #5
0
 def generate_new_lines(self):
     self.lines.clear()
     self.active_lines.clear()
     max_l = 50
     t = 1
     for i in range(100):
         x, y = [
             randint(-self.w//2 + t*max_l, self.w // 2 - t*max_l),
             randint(-self.h//2 + t*max_l, self.h // 2 - t*max_l)
         ]
         offset = v2([x, y])
         a = v2([0, 0]) + offset
         b = v3([randint(10, self.max_l), 0, 0]).rotate(0, 0, randint(0, 360)).to_v2() + offset
         self.lines.append(
             Line(a, b)
         )
     self.repaint()
コード例 #6
0
ファイル: Curves.py プロジェクト: ChMcg/CG
 def calculate(self):
     x = [point.x for point in self.points]
     y = [point.y for point in self.points]
     n = self.n
     self.spline_points.clear()
     for t in linspace(0, 1, 50):
         tmp_x = sum([self.N(i, n, t) * x[i] for i in range(0, n + 1)])
         tmp_y = sum([self.N(i, n, t) * y[i] for i in range(0, n + 1)])
         self.spline_points.append(v2((tmp_x, tmp_y)))
コード例 #7
0
ファイル: Curves.py プロジェクト: ChMcg/CG
 def __init__(self, points: List[v3] = default_points):
     self.points: List[v2] = points
     # print(points)
     self.n = len(points) - 1
     self.point = v2((0, 0))
     self.current_point = self.points[0]
     self.current_index = 0
     self.spline_points: List[v2] = []
     self.calculate()
コード例 #8
0
 def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
     if self.mouse_grabbed:
         x, y = event.x(), event.y()
         self.poly.move_point(
             v2([
                 x - self.w//2,
                 y - self.h//2
             ])
         )
     self.repaint()
コード例 #9
0
 def contains(self, point: v2, offset: QPoint):
     temp_line = Line(point, v2([self.x_r_max + 2, point.y]))
     cnt = 0
     for line in self.lines:
         intersection = line.intersection(temp_line, self.cache)
         if line.contains(intersection) and temp_line.contains(
                 intersection):
             cnt += 1
     if cnt % 2 == 0:
         return False
     else:
         return True
コード例 #10
0
 def mouseMoveEvent(self, event: QtGui.QMouseEvent) -> None:
     if self.mouse_grabbed:
         x, y = event.x(), event.y()
         self.figures[self.cf].move_point(
             v2([
                 x - self.w//2,
                 y - self.h//2
             ])
         )
         if self.update_on_mouse_move:
             self.update_cache()
     self.repaint()
コード例 #11
0
 def generate_figures(self) ->  Dict[Tuple[int, str], Figure]:
     ret = {}
     ret[(0, 'Треугольник')] = Polygon([
         v2([  0,  0]),
         v2([100,  0]),
         v2([  0,200]),
     ])
     ret[(1, 'Четырёхугольник')] = Polygon([
         v2([  0,  0]),
         v2([100,  0]),
         v2([100,200]),
         v2([  0,200]),
     ])
     return ret
コード例 #12
0
 def __init__(self, parent: QtWidgets.QWidget):
     super().__init__(parent)
     self.setMouseTracking(True)
     self.mouse_grabbed = False
     self.setGeometry(parent.geometry())
     self.setMinimumSize(550, 550)
     # self.setSizePolicy(parent.sizePolicy())
     parent.resize(parent.minimumSize())
     self.handle_resize()
     self.line = Line(v2([20, 20]), v2([50, 60]))
     self.lines: List[Line] = []
     self.limit = 0
     self.poly = Polygon(
         [
             v2([  0,   0]),
             v2([  0, 200]),
             v2([200, 200]),
             v2([200,   0]),
         ],
     )
     self.max_l = 50
     self.active_lines = set()
     self.generate_new_lines()
     self.partially_visible_lines: List[Line] = []
コード例 #13
0
                                          # QtCore.Qt.OddEvenFill
                                          )

    def move_point(self, pos: v2):
        self.points[self.ci] = pos
        # if self.x_r_max < pos.x:
        #     self.x_r_max = pos.x
        #TODO: хранить индекс самой правой точки
        self.x_r_max = max([point.x for point in self.points])
        self.regenerate_lines()

    def get_points(self) -> List[Point]:
        return self.points

    def get_all_intersections(self, other_line: Line) -> List[Point]:
        ret = []
        for line in self.lines:
            intersection = line.intersection(other_line, self.cache)
            if line.contains(intersection) and other_line.contains(
                    intersection):
                ret.append(intersection)
                # return intersection
        return ret


if __name__ == "__main__":
    a = Line(v2([0, 1]), v2([6, 4]))
    b = Line(v2([8, 8]), v2([8, 0]))
    C = a.intersection(b)
    p = v2([0, 1])
コード例 #14
0
 def set_point(self, x, y):
     self.point = v2((x, y))
     self.repaint()
コード例 #15
0
    def update_cache(self):
        self.cache.clear()
        h, w = [self.geometry().height(), self.geometry().width()]
        # lines = [Line(v2([0,y]), v2([w,y])) for y in range(0,h,3)]
        c = self.center
        cache = []
        new_cache= {}

        for y in range(0, h, self.line_period):
            line = Line(
                    v2([
                        0 - c.x(),
                        y - c.y()
                    ]), 
                    v2([
                        w - c.x(),
                        y - c.y()
                    ]), 
                )
            line_cache = []
            cl = -1
            current_color = [QtGui.QColor(0xFF0000),]
            tmp: List[Tuple[Point, str, QtGui.QColor]] = []
            intersection = []
            for i, figure in enumerate(self.figures):
                intersection = figure.get_all_intersections(line)
                if len(intersection) == 2:
                    # intersection.sort(key=lambda point: point.x)
                    A, B = intersection
                    if A.x > B.x:
                        A, B = B, A 
                    tmp.append((A, 'start', i, self.colors[i]))
                    tmp.append((B,  'stop', i, self.colors[i]))
                # print(len(intersection))

            if len(tmp) > 0:
                tmp.sort(key=lambda item: item[0].x)
                for a,b in zip(tmp[::1], tmp[1::1]):
                    a_point, a_state, a_layer, a_color = a 
                    b_point, b_state, b_layer, b_color = b
                    if a_state == 'start':
                        if a_layer > cl:
                            cl = a_layer
                            current_color.append(a_color)
                            line_cache.append(
                                (
                                    Line(
                                        # a_point,
                                        v2([a_point.x + 2, b_point.y]),
                                        b_point
                                        # v2([b_point.x-1, b_point.y])
                                    ), a_color
                                )
                            )
                        else:
                            line_cache.append(
                                (
                                    Line(
                                        # a_point,
                                        v2([a_point.x + 2, b_point.y]),
                                        b_point
                                        # v2([b_point.x-1, b_point.y])
                                    ), current_color[-1]
                                )
                            )
                        if b_state == 'stop':
                            if b_layer == cl:
                                cl = -1
                                current_color.pop()
                    else: # a - stop
                        if a_layer == cl:
                            cl = -1
                            current_color.pop()
                        if b_state == 'start':
                            if cl > -1:
                                line_cache.append(
                                    (
                                        Line(
                                            # a_point,
                                            v2([a_point.x + 2, b_point.y]),
                                            b_point
                                            # v2([b_point.x-1, b_point.y])
                                        ), current_color[-1]
                                    )
                                )

                                pass
                            else: # no layer
                                pass
                            pass
                        else: # b - stop
                            if cl > -1:
                                line_cache.append(
                                    (
                                        Line(
                                            # a_point,
                                            v2([a_point.x + 2, b_point.y]),
                                            b_point
                                            # v2([b_point.x-1, b_point.y])
                                        ), current_color[-1]
                                    )
                                )
                            else: # cl == -1
                                line_cache.append(
                                    (
                                        Line(
                                            # a_point,
                                            v2([a_point.x + 2, b_point.y]),
                                            b_point
                                            # v2([b_point.x-1, b_point.y])
                                        ), b_color
                                    )
                                )

                            pass
                        pass
            cache.append(line_cache)
            new_cache[y] = line_cache
        self.cache = cache