Example #1
0
 def draw_clock_hand(self, canvas):
     inner_p = (int(self.rng1 * math.cos(math.radians(self.theta)) +
                    self.center[0]),
                int(-self.rng1 * math.sin(math.radians(self.theta)) +
                    self.center[1]))
     outer_p = (int(self.rng2 * math.cos(math.radians(self.theta)) +
                    self.center[0]),
                int(-self.rng2 * math.sin(math.radians(self.theta)) +
                    self.center[1]))
     cv2.line(canvas,
              inner_p,
              outer_p,
              color_to_byte(PALE_GRAY),
              thickness=2)
     # 時計の針の先
     # 楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
     start_angle = int(self.theta - self.unit_arc / 2)
     end_angle = int(self.theta + self.unit_arc / 2)
     if start_angle == end_angle:
         end_angle += 1  # 差が 0 だと変なとこ描画するんで
     cv2.ellipse(canvas,
                 self.center, (self.rng2, self.rng2),
                 0,
                 360 - start_angle,
                 360 - end_angle,
                 color_to_byte(PALE_GRAY),
                 thickness=self.tickness)
     cv2.ellipse(canvas,
                 self.center, (self.rng3, self.rng3),
                 0,
                 360 - start_angle,
                 360 - end_angle,
                 color_to_byte(PALE_GRAY),
                 thickness=self.tickness)
Example #2
0
    def draw_border(self, canvas):
        """背景の左限、右限の線"""

        diameter = 2 * self.range1
        half_height = diameter * math.tan(math.radians(30))

        # 角30°の補助線(外接する矩形の縦幅の1/4)
        #left = int(self.center[0])
        #top = int(self.center[1]-self.range1 * math.tan(math.radians(30)))
        #right = int(self.center[0]+self.range1)
        #bottom = int(self.center[1])
        # cv2.line(canvas,
        #         (right, top),
        #         (left, bottom),
        #         color_to_byte(BLUE),
        #         thickness=1)

        # 角60°の補助線(定義から、外接する矩形の左上の角)
        #left = int(self.center[0]-self.range1)
        #top = int(self.center[1]-diameter * math.tan(math.radians(30)))
        #right = int(self.center[0])
        #bottom = int(self.center[1])
        # cv2.line(canvas,
        #         (left, top),
        #         (right, bottom),
        #         color_to_byte(RED),
        #         thickness=2)

        # 角270°の補助線(南側の垂線)
        #left = int(self.center[0])
        #top = int(self.center[1])
        #right = int(self.center[0])
        #bottom = int(self.center[1] + diameter * math.tan(math.radians(30)))
        # cv2.line(canvas,
        #         (left, top),
        #         (right, bottom),
        #         color_to_byte(PALE_GRAY),
        #         thickness=1)

        # 矩形
        left = int(self.center[0] - self.range1)
        top = int(self.center[1] - half_height)
        right = int(self.center[0] + self.range1)
        bottom = int(self.center[1] + half_height)
        cv2.rectangle(canvas, (left, top), (right, bottom),
                      color_to_byte(PALE_GRAY),
                      thickness=2)

        # 左限の線
        cv2.line(canvas,
                 (int(self.center[0] - self.range1), self.__drawing_top),
                 (int(self.center[0] - self.range1), self.__drawing_bottom),
                 color_to_byte(PALE_GRAY),
                 thickness=2)
        # 右限の線
        cv2.line(canvas,
                 (int(self.center[0] + self.range1), self.__drawing_top),
                 (int(self.center[0] + self.range1), self.__drawing_bottom),
                 color_to_byte(PALE_GRAY),
                 thickness=2)
Example #3
0
    def draw_border(self, canvas):
        """背景の左限、右限の線"""

        diameter = 2 * self.range1
        half_height = diameter * math.tan(math.radians(30))

        # 矩形
        left = int(self.center[0] - self.range1)
        top = int(self.center[1] - half_height)
        right = int(self.center[0] + self.range1)
        bottom = int(self.center[1] + half_height)
        cv2.rectangle(canvas, (left, top), (right, bottom),
                      color_to_byte(PALE_GRAY),
                      thickness=2)

        # 左限の線
        cv2.line(canvas,
                 (int(self.center[0] - self.range1), self.__drawing_top),
                 (int(self.center[0] - self.range1), self.__drawing_bottom),
                 color_to_byte(PALE_GRAY),
                 thickness=2)
        # 右限の線
        cv2.line(canvas,
                 (int(self.center[0] + self.range1), self.__drawing_top),
                 (int(self.center[0] + self.range1), self.__drawing_bottom),
                 color_to_byte(PALE_GRAY),
                 thickness=2)
Example #4
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle, inscribed_triangle,
                clock_hand):
    """アニメの1コマを作成します"""

    circle_rail.draw_circle(canvas)  # 円レール
    circle_rail.draw_triangle(canvas)  # 円に内接する正三角形
    circle_rail.draw_border(canvas)  # 背景の上限、下限の線

    inscribed_triangle.draw(canvas)

    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_x_axis_label(canvas)  # X軸のラベル

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    cv2.line(canvas,
             inscribed_triangle.rbg_points[0],
             (bar_box.red_right, bar_box.red_top),
             color_to_byte(RED),
             thickness=2)

    # 水平線G
    cv2.line(
        canvas,
        inscribed_triangle.rbg_points[2],  # 青と緑が入れ替わっているのが工夫
        (bar_box.green_right, bar_box.green_top),
        color_to_byte(GREEN),
        thickness=2)

    # 水平線B
    cv2.line(canvas,
             inscribed_triangle.rbg_points[1],
             (bar_box.blue_right, bar_box.blue_top),
             color_to_byte(BLUE),
             thickness=2)

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    clock_hand.draw_clock_hand(canvas)

    # バー箱の2段目の黒枠
    bar_box.draw_rank2_box(canvas)

    # 色成分数
    # 1色成分
    n3bars_width = bar_box.create_3bars_width()
    color = convert_3bars_to_3bytes(n3bars_width, bar_box.width)
    bar_box.draw_rgb_number(canvas, color)

    return canvas
Example #5
0
    def draw_me(self, canvas):
        """描きます"""
        # 色相環
        color_count = len(self.color_list)
        # print(
        #    f"color_count={color_count} self.area_size=({self.area_size[0]}, {self.area_size[1]})")
        for i in range(0, color_count):
            theta = i * self.unit_arc
            color = self.color_list[i]
            # print(f"[{i}] theta={theta} color={color}")

            # 円弧
            # 楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
            start_angle = int(theta - self.unit_arc / 2)
            end_angle = int(theta + self.unit_arc / 2)
            if start_angle == end_angle:
                end_angle += 1  # 差が 0 だと変なとこ描画するんで
            cv2.ellipse(canvas,
                        self.origin,
                        self.area_size,
                        0,
                        360 - start_angle,
                        360 - end_angle,
                        color_to_byte(color),
                        thickness=self.tickness)
Example #6
0
 def draw_blue_p(self, canvas):
     """円周上の点Bを描きます"""
     cv2.circle(canvas,
                self.blue_p,
                self.point_range,
                color_to_byte(BLUE),
                thickness=-1)
Example #7
0
 def draw_green_p(self, canvas):
     """円周上の点Gを描きます"""
     cv2.circle(canvas,
                self.green_p,
                self.point_range,
                color_to_byte(GREEN),
                thickness=-1)
Example #8
0
 def draw_red_p(self, canvas):
     """円周上の点Rを描きます"""
     cv2.circle(canvas,
                self.red_p,
                self.point_range,
                color_to_byte(RED),
                thickness=-1)
Example #9
0
 def draw_triangle(self, canvas):
     """円に内接する線。正三角形"""
     cv2.line(canvas,
              self.red_p,
              self.green_p,
              color_to_byte(WHITE),
              thickness=2)
     cv2.line(canvas,
              self.green_p,
              self.blue_p,
              color_to_byte(WHITE),
              thickness=2)
     cv2.line(canvas,
              self.blue_p,
              self.red_p,
              color_to_byte(WHITE),
              thickness=2)
Example #10
0
 def draw_circle(self, canvas):
     """描きます"""
     # 円レール。描画する画像を指定、座標(x,y),半径、色、線の太さ(-1は塗りつぶし)
     cv2.circle(canvas,
                self.center,
                self.range1,
                color_to_byte(WHITE),
                thickness=2)
Example #11
0
def draw_tone_name(canvas, bar_box, tone_name):
    """トーン名を描きます"""
    line_type = 2
    cv2.putText(
        canvas,
        f"{tone_name}",
        (bar_box.left, int(BAR_BOX_TOP - 3.5 * GRID_UNIT)),  # x,y
        cv2.FONT_HERSHEY_SIMPLEX,
        FONT_SCALE,
        color_to_byte(DARK_GRAYISH_GRAY),
        line_type)
    cv2.putText(
        canvas,
        f"tone diameter",
        (bar_box.left + GRID_UNIT, int(BAR_BOX_TOP - 2.5 * GRID_UNIT)),  # x,y
        cv2.FONT_HERSHEY_SIMPLEX,
        FONT_SCALE,
        color_to_byte(DARK_GRAYISH_GRAY),
        line_type)
Example #12
0
 def draw(self, canvas):
     """描きます"""
     cv2.line(canvas,
              self.rbg_points[0],
              self.rbg_points[1],
              color_to_byte(BLACK),
              thickness=2)
     cv2.line(canvas,
              self.rbg_points[1],
              self.rbg_points[2],
              color_to_byte(BLACK),
              thickness=2)
     cv2.line(canvas,
              self.rbg_points[2],
              self.rbg_points[0],
              color_to_byte(BLACK),
              thickness=2)
     cv2.circle(canvas,
                self.rbg_points[0],
                int(GRID_UNIT / 4),
                color_to_byte(RED),
                thickness=-1)
     cv2.circle(canvas,
                self.rbg_points[1],
                int(GRID_UNIT / 4),
                color_to_byte(BLUE),
                thickness=-1)
     cv2.circle(canvas,
                self.rbg_points[2],
                int(GRID_UNIT / 4),
                color_to_byte(GREEN),
                thickness=-1)
Example #13
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle, inscribed_triangle,
                clock_hand):
    """アニメの1コマを作成します"""

    circle_rail.draw_circle(canvas)  # 円レール
    circle_rail.draw_triangle(canvas)  # 円に内接する正三角形
    circle_rail.draw_border(canvas)  # 背景の上限、下限の線

    inscribed_triangle.draw(canvas)

    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_x_axis_label(canvas)  # X軸のラベル

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    cv2.line(canvas,
             inscribed_triangle.rbg_points[0],
             (bar_box.red_right, bar_box.red_top),
             color_to_byte(RED),
             thickness=2)

    # 水平線G
    cv2.line(
        canvas,
        inscribed_triangle.rbg_points[2],  # 青と緑が入れ替わっているのが工夫
        (bar_box.green_right, bar_box.green_top),
        color_to_byte(GREEN),
        thickness=2)

    # 水平線B
    cv2.line(canvas,
             inscribed_triangle.rbg_points[1],
             (bar_box.blue_right, bar_box.blue_top),
             color_to_byte(BLUE),
             thickness=2)

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    clock_hand.draw_clock_hand(canvas)

    # バー箱の2段目の黒枠
    bar_box.draw_rank2_box(canvas)

    # 色成分数
    # 1色成分
    n3bars_width = bar_box.create_3bars_width()
    color = convert_3bars_to_3bytes(n3bars_width, bar_box.width)
    bar_box.draw_rgb_number(canvas, color)

    # gravity = inscribed_triangle.triangular_center_of_gravity()

    # debug
    # cv2.putText(canvas,
    #            f"theta={circle_rail.theta}",
    #            # f"theta={circle_rail.theta} phase={outer_circle.phase} \
    #  gravity=({gravity[0]:5.1f}, {gravity[1]:5.1f})",
    #            (10, 10),  # x,y
    #            cv2.FONT_HERSHEY_SIMPLEX,
    #            FONT_SCALE,
    #            color_to_byte(BLACK),
    #            lineType=2)
    # f"multiple=({n3bars_multiple[0]:7.3f}, {n3bars_multiple[1]:7.3f}, {n3bars_multiple[2]:7.3f})",

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas
Example #14
0
def make_canvas():
    """キャンバス生成"""
    return np.full((CANVAS_HEIGHT, CANVAS_WIDTH, CHANNELS),
                   color_to_byte(SOFT_GRAY)[0],
                   dtype=np.uint8)
Example #15
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle, inscribed_triangle,
                clock_hand):
    """アニメの1コマを作成します"""

    circle_rail.draw_circle(canvas)  # 円レール
    circle_rail.draw_triangle(canvas)  # 円に内接する正三角形
    circle_rail.draw_border(canvas)  # 背景の上限、下限の線

    inscribed_triangle.draw(canvas)

    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_x_axis_label(canvas)  # X軸のラベル

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    cv2.line(canvas,
             inscribed_triangle.rbg_points[0],
             (bar_box.red_right, bar_box.red_top),
             color_to_byte(RED),
             thickness=2)

    # 水平線G
    cv2.line(
        canvas,
        inscribed_triangle.rbg_points[2],  # 青と緑が入れ替わっているのが工夫
        (bar_box.green_right, bar_box.green_top),
        color_to_byte(GREEN),
        thickness=2)

    # 水平線B
    cv2.line(canvas,
             inscribed_triangle.rbg_points[1],
             (bar_box.blue_right, bar_box.blue_top),
             color_to_byte(BLUE),
             thickness=2)

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    clock_hand.draw_clock_hand(canvas)

    # バー箱の2段目の黒枠
    bar_box.draw_rank2_box(canvas)

    # 色成分数
    # 1色成分
    n3bars_width = bar_box.create_3bars_width()
    color = convert_3bars_to_3bytes(n3bars_width, bar_box.width)
    bar_box.draw_rgb_number(canvas, color)

    # テスト
    red = n3bars_width[0]
    green = n3bars_width[1]
    blue = n3bars_width[2]

    upper = max(red, green, blue)
    lower = min(red, green, blue)
    bar_width = red + green + blue - upper - lower - lower
    diameter = upper - lower
    radius = diameter / 2
    tanjent = diameter - bar_width - radius
    opposite = (math.sqrt(3) / 2) * tanjent
    adjacent = radius
    hipotenuse = math.sqrt(adjacent**2 + opposite**2)
    ex_radius = 2 * math.tan(math.radians(30)) * radius
    ex_adjacent = ex_radius
    ex_hipotenuse = math.sqrt(ex_adjacent**2 + tanjent**2)

    # テスト タンジェント
    left = int(circle_rail.center[0] - tanjent)
    top = int(circle_rail.center[1] - ex_radius)
    right = int(circle_rail.center[0])
    bottom = int(circle_rail.center[1] - ex_radius)
    cv2.line(canvas, (left, top), (right, bottom),
             color_to_byte(GREEN),
             thickness=4)

    # テスト対辺
    left = int(circle_rail.center[0] - opposite)
    top = int(circle_rail.center[1] - circle_rail.range1)
    right = int(circle_rail.center[0])
    bottom = int(circle_rail.center[1] - circle_rail.range1)
    cv2.line(canvas, (left, top), (right, bottom),
             color_to_byte(LIGHT_GREEN),
             thickness=4)

    # テスト底辺
    cv2.line(canvas,
             (circle_rail.center[0], int(circle_rail.center[1] - ex_adjacent)),
             (circle_rail.center[0], circle_rail.center[1]),
             color_to_byte(RED),
             thickness=4)

    # テスト底辺
    cv2.line(canvas,
             (circle_rail.center[0], int(circle_rail.center[1] - adjacent)),
             (circle_rail.center[0], circle_rail.center[1]),
             color_to_byte(LIGHT_RED),
             thickness=4)

    # atan だとずれる。 asin だとピッタリに見える(^~^)acosは向きが違う(^~^)
    #test_theta = math.degrees(math.acos(opposite / hipotenuse))
    test_theta = math.degrees(math.asin(opposite / hipotenuse))
    #test_theta = math.degrees(math.atan(opposite / hipotenuse))
    # テスト角度
    # cv2.ellipse(canvas,
    #            circle_rail.center,
    #            (2*circle_rail.range1, 2*circle_rail.range1),
    #            0,
    #            0,
    #            test_theta,
    #            color_to_byte(RED),
    #            thickness=4)

    # テスト斜辺
    point_x = ex_hipotenuse * \
        math.cos(math.radians(test_theta+90)) + circle_rail.center[0]
    point_y = ex_hipotenuse * \
        -math.sin(math.radians(test_theta+90)) + circle_rail.center[1]
    # print(f"point_x={point_x} point_y={point_y}")
    cv2.line(canvas, (circle_rail.center[0], circle_rail.center[1]),
             (int(point_x), int(point_y)),
             color_to_byte(BLUE),
             thickness=4)

    # テスト斜辺
    point_x = hipotenuse * \
        math.cos(math.radians(test_theta+90)) + circle_rail.center[0]
    point_y = hipotenuse * \
        -math.sin(math.radians(test_theta+90)) + circle_rail.center[1]
    # print(f"point_x={point_x} point_y={point_y}")
    cv2.line(canvas, (circle_rail.center[0], circle_rail.center[1]),
             (int(point_x), int(point_y)),
             color_to_byte(LIGHT_BLUE),
             thickness=4)

    # 角60°の補助線(定義から、外接する矩形の左上の角)
    #left = int(circle_rail.center[0]-circle_rail.range1)
    #top = int(circle_rail.center[1]-diameter * math.tan(math.radians(30)))
    #right = int(circle_rail.center[0])
    #bottom = int(circle_rail.center[1])
    # cv2.line(canvas,
    #         (left, top),
    #         (right, bottom),
    #         color_to_byte(RED),
    #         thickness=2)

    # gravity = inscribed_triangle.triangular_center_of_gravity()

    # debug
    # cv2.putText(canvas,
    #            f"theta={circle_rail.theta}",
    #            # f"theta={circle_rail.theta} phase={outer_circle.phase} \
    #  gravity=({gravity[0]:5.1f}, {gravity[1]:5.1f})",
    #            (10, 10),  # x,y
    #            cv2.FONT_HERSHEY_SIMPLEX,
    #            FONT_SCALE,
    #            color_to_byte(BLACK),
    #            lineType=2)
    # f"multiple=({n3bars_multiple[0]:7.3f}, {n3bars_multiple[1]:7.3f}, {n3bars_multiple[2]:7.3f})",

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas