コード例 #1
0
def make_circle(canvas, seq, bar_rates, tone_name):
    """色相環一周分の画像を出力"""

    outer_circle = OuterCircle()

    for phase in range(0, PHASE_COUNTS):
        theta = 360/PHASE_COUNTS*phase
        canvas = make_canvas()
        bar_box, circle_rail, outer_circle = make_scene1(
            bar_rates, outer_circle)
        outer_circle.phase = phase

        # 円周上の点の位置
        circle_rail.theta = theta

        # バーR
        bar_box.step1_rect[0].left_top = (
            bar_box.red_left, circle_rail.red_p[1])
        bar_box.step1_rect[0].right_bottom = (
            bar_box.red_left+bar_box.one_width, bar_box.top3)
        # バーG
        bar_box.step1_rect[1].left_top = (
            bar_box.green_left, circle_rail.green_p[1])
        bar_box.step1_rect[1].right_bottom = (
            bar_box.green_left+bar_box.one_width, bar_box.top3)
        # バーB
        bar_box.step1_rect[2].left_top = (
            bar_box.blue_left, circle_rail.blue_p[1])
        bar_box.step1_rect[2].right_bottom = (
            bar_box.blue_left+bar_box.one_width, bar_box.top3)
#        print(
#            f"red={bar_box.step1_rect[0].debug_string} \
# green={bar_box.step1_rect[1].debug_string} \
# blue={bar_box.step1_rect[2].debug_string}")

        bar_box.delta_3bars_height = calc_step2(
            bar_box.create_step1_3bars_height(),
            bar_box.height2
        )

        # 外環状
        theta = outer_circle.phase * outer_circle.unit_arc
        outer_color = convert_3heights_to_3bytes(
            bar_box.create_rank23d_3bars_height(), bar_box.height)
        outer_circle.color_list.append(outer_color)
        #

        draw_grid(canvas)  # 罫線
        bar_box.draw_outline(canvas)  # 箱の輪郭
        canvas = draw_canvas(canvas, bar_box, circle_rail,
                             outer_circle)
        draw_tone_name(canvas, bar_box, tone_name)  # トーン名

        # 書出し
        canvas = cv2.cvtColor(canvas, cv2.COLOR_BGR2RGB)  # BGRをRGBにする
        cv2.imwrite(f"./@share/out-cstep4-{seq}.png", canvas)
        seq += 1

    return seq, canvas
コード例 #2
0
def update_scene1_with_rotate(vertical_parcent, phase, bar_box, circle_rail,
                              outer_circle, inscribed_triangle):
    """回転が伴うモデルを更新"""
    theta = 360 / PHASE_COUNTS * phase

    outer_circle.phase = phase

    # 円周上の点の位置
    circle_rail.theta = theta

    #    print(
    #        f"vertical_parcent=({vertical_parcent[0]}, {vertical_parcent[1]}, \
    # {vertical_parcent[2]}) theta={theta}")
    color_rate = to_color_rate(vertical_parcent, theta)
    #    print(
    #        f"color_rate=({color_rate[0]}, {color_rate[1]}, {color_rate[2]})")

    # バーの高さに変換
    red_bar_height = int(color_rate[0] * bar_box.height)
    green_bar_height = int(color_rate[1] * bar_box.height)
    blue_bar_height = int(color_rate[2] * bar_box.height)
    #    print(
    #        f"red_bar_height={red_bar_height} green_bar_height={green_bar_height} \
    # blue_bar_height={blue_bar_height}")

    # バーR ( (left, top), (right, bottom) )
    # バーG
    # バーB
    bar_box.n3bars_rect = (Rectangle(bar_box.red_left,
                                     bar_box.bottom - red_bar_height,
                                     bar_box.red_left + bar_box.one_width,
                                     bar_box.top3),
                           Rectangle(bar_box.green_left,
                                     bar_box.bottom - green_bar_height,
                                     bar_box.green_left + bar_box.one_width,
                                     bar_box.top3),
                           Rectangle(bar_box.blue_left,
                                     bar_box.bottom - blue_bar_height,
                                     bar_box.blue_left + bar_box.one_width,
                                     bar_box.top3))

    # 外環状
    theta = outer_circle.phase * outer_circle.unit_arc
    rank23d_3bars_height = bar_box.create_rank23d_3bars_height()
    outer_circle.color_list.append(
        convert_3heights_to_3bytes(rank23d_3bars_height, bar_box.height))
    #

    inscribed_triangle.update(bar_box.top2, bar_box.top3, circle_rail.center,
                              theta, rank23d_3bars_height)

    gravity = inscribed_triangle.triangular_center_of_gravity()
    diff_xy = (gravity[0] - circle_rail.center[0],
               gravity[1] - circle_rail.center[1])
    inscribed_triangle.correct_horizon(diff_xy)
コード例 #3
0
def update_scene1_with_rotate(phase, bar_box, circle_rail, outer_circle,
                              inscribed_triangle):
    """回転が伴うモデルを更新"""
    theta = 360 / PHASE_COUNTS * phase

    outer_circle.phase = phase

    # 円周上の点の位置
    circle_rail.theta = theta

    # バーR
    bar_box.step1_rect[0].left_top = (bar_box.red_left, circle_rail.red_p[1])
    bar_box.step1_rect[0].right_bottom = (bar_box.red_left + bar_box.one_width,
                                          bar_box.top3)
    # バーG
    bar_box.step1_rect[1].left_top = (bar_box.green_left,
                                      circle_rail.green_p[1])
    bar_box.step1_rect[1].right_bottom = (bar_box.green_left +
                                          bar_box.one_width, bar_box.top3)
    # バーB
    bar_box.step1_rect[2].left_top = (bar_box.blue_left, circle_rail.blue_p[1])
    bar_box.step1_rect[2].right_bottom = (bar_box.blue_left +
                                          bar_box.one_width, bar_box.top3)
    #        print(
    #            f"red={bar_box.step1_rect[0].debug_string} \
    # green={bar_box.step1_rect[1].debug_string} \
    # blue={bar_box.step1_rect[2].debug_string}")

    bar_box.delta_3bars_height = calc_step2(
        bar_box.create_step1_3bars_height(), bar_box.height2)

    # 外環状
    theta = outer_circle.phase * outer_circle.unit_arc
    rank23d_3bars_height = bar_box.create_rank23d_3bars_height()
    outer_color = convert_3heights_to_3bytes(rank23d_3bars_height,
                                             bar_box.height)
    outer_circle.color_list.append(outer_color)
    #

    inscribed_triangle.update(bar_box.top2, bar_box.top3, circle_rail.center,
                              theta, rank23d_3bars_height)
    gravity = inscribed_triangle.triangular_center_of_gravity()
    diff_xy = (gravity[0] - circle_rail.center[0],
               gravity[1] - circle_rail.center[1])
    inscribed_triangle.correct_horizon(diff_xy)
コード例 #4
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle,
                inscribed_triangle):
    """アニメの1コマを作成します"""

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

    inscribed_triangle.draw(canvas)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    rank23d_3bars_height = bar_box.create_rank23d_3bars_height()
    rank23d_color = convert_3heights_to_3bytes(rank23d_3bars_height,
                                               bar_box.height)
    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_y_axis_label(canvas)  # バー率テキスト

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

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

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

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    tickness = 2
    inner_range = circle_rail.range1
    second_range = int(6.5 * GRID_UNIT) - tickness
    third_range = int(7.5 * GRID_UNIT) + tickness
    inner_p = (
        int(inner_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(inner_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    outer_p = (
        int(second_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(second_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, PALE_GRAY, thickness=2)
    # 時計の針の先
    # 楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
    start_angle = int(circle_rail.theta - outer_circle.unit_arc / 2)
    end_angle = int(circle_rail.theta + outer_circle.unit_arc / 2)
    if start_angle == end_angle:
        end_angle += 1  # 差が 0 だと変なとこ描画するんで
    cv2.ellipse(canvas,
                circle_rail.center, (second_range, second_range),
                -90,
                start_angle,
                end_angle,
                PALE_GRAY,
                thickness=tickness)
    cv2.ellipse(canvas,
                circle_rail.center, (third_range, third_range),
                -90,
                start_angle,
                end_angle,
                PALE_GRAY,
                thickness=tickness)
    #

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

    # 色成分数
    bar_box.draw_rgb_number(canvas, rank23d_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,
    #            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
コード例 #5
0
def draw_canvas(canvas, bar_box, circle_rail, inner_circle, outer_circle):
    """アニメの1コマを作成します"""

    circle_rail.draw_me(canvas)  # 円レール

    circle_rail.draw_red_p(canvas)  # 円周上の点R
    circle_rail.draw_green_p(canvas)  # 円周上の点G
    circle_rail.draw_blue_p(canvas)  # 円周上の点B

    # 円に内接する線。三角形
    cv2.line(canvas,
             circle_rail.red_p,
             circle_rail.green_p,
             BLACK,
             thickness=2)
    cv2.line(canvas,
             circle_rail.green_p,
             circle_rail.blue_p,
             BLACK,
             thickness=2)
    cv2.line(canvas, circle_rail.blue_p, circle_rail.red_p, BLACK, thickness=2)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    a_color = convert_3heights_to_3bytes(bar_box.addition_3bars_height,
                                         bar_box.height)
    step1_color = convert_3heights_to_3bytes(
        bar_box.create_step1_3bars_height(), bar_box.height)
    rank3_color = convert_3heights_to_3bytes(
        bar_box.create_rank3_3bars_height(), bar_box.height)
    rank23_color = convert_3heights_to_3bytes(
        bar_box.create_rank23_3bars_height(), bar_box.height)
    rank23a_color = convert_3heights_to_3bytes(
        bar_box.create_rank23a_3bars_height(), bar_box.height)
    # 3色成分(配色)
    a_3colors = (DARK_RED, DARK_GREEN, DARK_BLUE)
    step1_3colors = (VIVID_RED, VIVID_GREEN, VIVID_BLUE)
    rank3_3colors = (BRIGHT_RED, BRIGHT_GREEN, BRIGHT_BLUE)
    rank23a_3colors = (RED, GREEN, BLUE)

    #    # (WIP) 成分から角度を逆算
    #    element_rates, expected_theta = calc_color_element_rates(rank23_color)
    #    if circle_rail.theta != expected_theta:
    #        print(
    #            f"theta={circle_rail.theta:>7.3f}~{expected_theta:>7.3f} \
    # color_element(rank23_color)=({element_rates[0]:>7.3f}, \
    # {element_rates[1]:>7.3f}, \
    # {element_rates[2]:>7.3f})")
    bar_box.draw_3bars(canvas, a_3colors, step1_3colors,
                       rank3_3colors)  # RGBバー

    # 色見本 筆算の線
    line_left = bar_box.left - 14 * GRID_INTERVAL_H
    line_right = bar_box.right + 4 * GRID_INTERVAL_H
    line_top = bar_box.bottom + int(13 * GRID_INTERVAL_H)
    cv2.line(canvas, (line_left, line_top), (line_right, line_top),
             LIGHT_GRAY,
             thickness=2)

    # プラス記号
    color_example_width = 3 * GRID_INTERVAL_H
    font = cv2.FONT_HERSHEY_SIMPLEX
    font_scale = FONT_SCALE
    line_type = 2
    cv2.putText(
        canvas,
        "+",
        (int(bar_box.left - 4.5 * color_example_width),
         int(bar_box.bottom + 11.5 * GRID_INTERVAL_H)),  # x,y
        font,
        font_scale,
        BLACK,
        line_type)
    color_example_left = int(bar_box.left - 1.5 * color_example_width)

    # 括線
    cv2.ellipse(canvas, (bar_box.left - GRID_INTERVAL_H,
                         bar_box.bottom + int(8.5 * GRID_INTERVAL_H)),
                (3 * GRID_INTERVAL_H, 3 * GRID_INTERVAL_H),
                90,
                0,
                180,
                PALE_GRAY,
                thickness=2)

    # 色見本 rank23
    left_top = (int(color_example_left - 3.5 * GRID_INTERVAL_H),
                int(bar_box.bottom + int(7.5 * GRID_INTERVAL_H)))
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23_color,
                  thickness=-1)  # 色見本

    # 色見本 23a
    left_top = (color_example_left,
                int(bar_box.bottom + int(14.5 * GRID_INTERVAL_H)))
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23a_color,
                  thickness=-1)  # 色見本

    bar_box.draw_bar_rate_rank13(canvas)  # バー率テキスト
    bar_box.draw_bar_rate_rank2(canvas)  # バー率テキスト

    # 色成分数
    bar_box.draw_rgb_number(canvas, a_color, a_3colors, step1_color,
                            step1_3colors, rank3_color, rank3_3colors,
                            rank23a_color, rank23a_3colors)

    # 時計の針
    clock_hand_len = 8 * GRID_INTERVAL_H
    inner_p = (int(circle_rail.range *
                   math.cos(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[0]),
               int(circle_rail.range *
                   math.sin(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[1]))
    outer_p = (int((circle_rail.range + clock_hand_len) *
                   math.cos(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[0]),
               int((circle_rail.range + clock_hand_len) *
                   math.sin(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, LIGHT_GRAY, thickness=2)

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    cv2.line(canvas,
             circle_rail.red_p,
             (bar_box.step1_rect[0].right_bottom[0], circle_rail.red_p[1]),
             step1_3colors[0],
             thickness=2)

    # 水平線G
    cv2.line(canvas,
             circle_rail.green_p,
             (bar_box.step1_rect[1].right_bottom[0], circle_rail.green_p[1]),
             step1_3colors[1],
             thickness=2)

    # 水平線B
    cv2.line(canvas,
             circle_rail.blue_p,
             (bar_box.step1_rect[2].right_bottom[0], circle_rail.blue_p[1]),
             step1_3colors[2],
             thickness=2)

    inner_circle.draw_me(canvas)  # 内環状
    outer_circle.draw_me(canvas)  # 外環状

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas
コード例 #6
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle):
    """アニメの1コマを作成します"""

    circle_rail.draw_me(canvas)  # 円レール

    circle_rail.draw_red_p(canvas)  # 円周上の点R
    circle_rail.draw_green_p(canvas)  # 円周上の点G
    circle_rail.draw_blue_p(canvas)  # 円周上の点B

    # 背景の上限、下限の線
    cv2.line(canvas,
             (circle_rail.center[0] - 2*circle_rail.range,
              int(circle_rail.center[1] - circle_rail.range)),
             (circle_rail.center[0] + 2*circle_rail.range,
              int(circle_rail.center[1] - circle_rail.range)),
             PALE_GRAY, thickness=2)
    cv2.line(canvas,
             (circle_rail.center[0] - 2*circle_rail.range,
              int(circle_rail.center[1] + circle_rail.range)),
             (circle_rail.center[0] + 2*circle_rail.range,
              int(circle_rail.center[1] + circle_rail.range)),
             PALE_GRAY, thickness=2)

    # 円に内接する線。正三角形
    cv2.line(canvas, circle_rail.red_p,
             circle_rail.green_p, WHITE, thickness=2)
    cv2.line(canvas, circle_rail.green_p,
             circle_rail.blue_p, WHITE, thickness=2)
    cv2.line(canvas, circle_rail.blue_p,
             circle_rail.red_p, WHITE, thickness=2)

    # 調整された三角形
    # bar_box.create_rank23d_3bars_height()
    n3bars_multiple = bar_box.create_3bars_multiple()
    circle_rail.calc_fitted_p(n3bars_multiple)
    cv2.line(canvas, circle_rail.fitted_red_p,
             circle_rail.fitted_green_p, BLACK, thickness=2)
    cv2.line(canvas, circle_rail.fitted_green_p,
             circle_rail.fitted_blue_p, BLACK, thickness=2)
    cv2.line(canvas, circle_rail.fitted_blue_p,
             circle_rail.fitted_red_p, BLACK, thickness=2)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    rank23d_color = convert_3heights_to_3bytes(
        bar_box.create_rank23d_3bars_height(), bar_box.height)

#    # (WIP) 成分から角度を逆算
#    element_rates, expected_theta = calc_color_element_rates(rank23_color)
#    if circle_rail.theta != expected_theta:
#        print(
#            f"theta={circle_rail.theta:>7.3f}~{expected_theta:>7.3f} \
# color_element(rank23_color)=({element_rates[0]:>7.3f}, \
# {element_rates[1]:>7.3f}, \
# {element_rates[2]:>7.3f})")
    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_y_axis_label(canvas)  # バー率テキスト

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    top = bar_box.step1_rect[0].left_top[1] - bar_box.delta_3bars_height[0]
    cv2.line(canvas,
             circle_rail.fitted_red_p,
             (bar_box.step1_rect[0].left_top[0], top),
             RED, thickness=2)

    # 水平線G
    top = bar_box.step1_rect[1].left_top[1] - bar_box.delta_3bars_height[1]
    cv2.line(canvas,
             circle_rail.fitted_green_p,
             (bar_box.step1_rect[1].left_top[0], top),
             GREEN, thickness=2)

    # 水平線B
    top = bar_box.step1_rect[2].left_top[1] - bar_box.delta_3bars_height[2]
    cv2.line(canvas,
             circle_rail.fitted_blue_p,
             (bar_box.step1_rect[2].left_top[0], top),
             BLUE, thickness=2)

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    tickness = 2
    inner_range = circle_rail.range
    second_range = int(6.5*GRID_UNIT)-tickness
    third_range = int(7.5*GRID_UNIT)+tickness
    inner_p = (
        int(inner_range * math.cos(math.radians(circle_rail.theta-90)) +
            circle_rail.center[0]),
        int(inner_range * math.sin(math.radians(circle_rail.theta-90))+circle_rail.center[1]))
    outer_p = (
        int(second_range *
            math.cos(math.radians(circle_rail.theta-90))+circle_rail.center[0]),
        int(second_range * math.sin(math.radians(circle_rail.theta-90))
            + circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, PALE_GRAY, thickness=2)
    # 時計の針の先
    # 楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
    cv2.ellipse(canvas,
                circle_rail.center,
                (second_range, second_range),
                -90,
                int(circle_rail.theta-outer_circle.unit_arc/2),
                int(circle_rail.theta+outer_circle.unit_arc/2),
                PALE_GRAY,
                thickness=tickness)
    cv2.ellipse(canvas,
                circle_rail.center,
                (third_range, third_range),
                -90,
                int(circle_rail.theta-outer_circle.unit_arc/2),
                int(circle_rail.theta+outer_circle.unit_arc/2),
                PALE_GRAY,
                thickness=tickness)
    #

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

    # 色成分数
    bar_box.draw_rgb_number(canvas,
                            rank23d_color)

    # debug
    # cv2.putText(canvas,
    f"multiple=({n3bars_multiple[0]:7.3f}, {n3bars_multiple[1]:7.3f}, {n3bars_multiple[2]:7.3f})",
    # f"zoom={circle_rail.zoom}",
    #               # f"delta_color=({delta_color[0]}, {delta_color[1]}, {delta_color[2]})",
    #               f"delta_3bars_height=({bar_box.delta_3bars_height[0]}, \
    #    {bar_box.delta_3bars_height[1]}, \
    #    {bar_box.delta_3bars_height[2]})",
    # (10, 10),  # x,y
    # cv2.FONT_HERSHEY_SIMPLEX,
    # FONT_SCALE,
    # BLACK,
    # lineType=2)

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas
コード例 #7
0
def draw_canvas(canvas, bar_box, circle_rail, outer_circle):
    """アニメの1コマを作成します"""

    circle_rail.draw_circle(canvas)  # 円レール
    circle_rail.draw_triangle(canvas)  # 円に内接する線。正三角形

    circle_rail.draw_red_p(canvas)  # 円周上の点R
    circle_rail.draw_green_p(canvas)  # 円周上の点G
    circle_rail.draw_blue_p(canvas)  # 円周上の点B

    # 背景の上限、下限の線
    cv2.line(canvas, (circle_rail.center[0] - 2 * circle_rail.range,
                      int(circle_rail.center[1] - circle_rail.range)),
             (circle_rail.center[0] + 2 * circle_rail.range,
              int(circle_rail.center[1] - circle_rail.range)),
             PALE_GRAY,
             thickness=2)
    cv2.line(canvas, (circle_rail.center[0] - 2 * circle_rail.range,
                      int(circle_rail.center[1] + circle_rail.range)),
             (circle_rail.center[0] + 2 * circle_rail.range,
              int(circle_rail.center[1] + circle_rail.range)),
             PALE_GRAY,
             thickness=2)

    # 調整された三角形
    # 赤、緑、青 の点の位置関係は全部で12相です
    rank23d_3bars_height = bar_box.create_rank23d_3bars_height()
    red = rank23d_3bars_height[0]
    green = rank23d_3bars_height[1]
    blue = rank23d_3bars_height[2]
    triangle_theta = circle_rail.theta  # +phase*30
    if green == blue and blue < red:
        # 緑と青は等しく、それより赤が上
        phase = 0
    elif blue < green and green < red:
        # 下から青、緑、赤
        phase = 1
    elif blue < green and green == red:
        # 青より大きい緑は赤と等しい
        phase = 2
    elif blue < red and red < green:
        # 下から青、赤、緑
        phase = 3
        triangle_theta -= 120
    elif blue == red and red < green:
        # 青と赤は等しく、それより緑が上
        phase = 4
        triangle_theta -= 120
    elif red < blue and blue < green:
        # 下から赤、青、緑
        phase = 5
        triangle_theta -= 120
    elif red < blue and blue == green:
        # 赤より大きい青は緑と等しい
        phase = 6
        triangle_theta -= 120
    elif red < green and green < blue:
        # 下から赤、緑、青
        phase = 7
        triangle_theta += 120
    elif red == green and green < blue:
        # 赤と緑は等しく、それより青が上
        phase = 8
        triangle_theta += 120
    elif green < red and red < blue:
        # 下から緑、赤、青
        phase = 9
        triangle_theta += 120
    elif green < red and red == blue:
        # 緑より大きい赤は青と等しい
        phase = 10
    else:
        # 下から緑、青、赤
        phase = 11
    # 赤、青、緑 の順なのが工夫
    rbg_points = calc_triangle(bar_box.top2, bar_box.top3, triangle_theta,
                               circle_rail.center)
    if phase == 0:
        # 緑や青より赤が上
        pass
    elif phase == 1:
        # 下から青、緑、赤
        pass
    elif phase == 2:
        # 青より、緑と赤が上
        pass
    elif phase == 3:
        # 下から青、赤、緑
        rbg_points = (rbg_points[2], rbg_points[1], rbg_points[0])
    elif phase == 4:
        # 青や赤より緑が上
        rbg_points = (rbg_points[1], rbg_points[2], rbg_points[0])
    elif phase == 5:
        # 下から赤、青、緑
        rbg_points = (rbg_points[1], rbg_points[2], rbg_points[0])
    elif phase == 6:
        # 赤より、青と緑が上
        rbg_points = (rbg_points[1], rbg_points[2], rbg_points[0])
    elif phase == 7:
        # 下から赤、緑、青
        rbg_points = (rbg_points[1], rbg_points[0], rbg_points[2])
    elif phase == 8:
        # 赤や緑より青が上
        rbg_points = (rbg_points[2], rbg_points[0], rbg_points[1])
    elif phase == 9:
        # 下から緑、赤、青
        rbg_points = (rbg_points[2], rbg_points[0], rbg_points[1])
    elif phase == 10:
        # 緑より、赤と青が上
        rbg_points = (rbg_points[0], rbg_points[2], rbg_points[1])
    else:
        # 下から緑、青、赤
        rbg_points = (rbg_points[0], rbg_points[2], rbg_points[1])

    cv2.line(canvas, rbg_points[0], rbg_points[1], BLACK, thickness=2)
    cv2.line(canvas, rbg_points[1], rbg_points[2], BLACK, thickness=2)
    cv2.line(canvas, rbg_points[2], rbg_points[0], BLACK, thickness=2)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    rank23d_color = convert_3heights_to_3bytes(rank23d_3bars_height,
                                               bar_box.height)

    #    # (WIP) 成分から角度を逆算
    #    element_rates, expected_theta = calc_color_element_rates(rank23_color)
    #    if circle_rail.theta != expected_theta:
    #        print(
    #            f"theta={circle_rail.theta:>7.3f}~{expected_theta:>7.3f} \
    # color_element(rank23_color)=({element_rates[0]:>7.3f}, \
    # {element_rates[1]:>7.3f}, \
    # {element_rates[2]:>7.3f})")
    bar_box.draw_3bars(canvas)  # RGBバー

    bar_box.draw_y_axis_label(canvas)  # バー率テキスト

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

    # 水平線G
    top = bar_box.step1_rect[1].left_top[1] - bar_box.delta_3bars_height[1]
    cv2.line(
        canvas,
        rbg_points[2],  # 青と緑が入れ替わっているのが工夫
        (bar_box.step1_rect[1].left_top[0], top),
        GREEN,
        thickness=2)

    # 水平線B
    top = bar_box.step1_rect[2].left_top[1] - bar_box.delta_3bars_height[2]
    cv2.line(canvas,
             rbg_points[1], (bar_box.step1_rect[2].left_top[0], top),
             BLUE,
             thickness=2)

    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    tickness = 2
    inner_range = circle_rail.range
    second_range = int(6.5 * GRID_UNIT) - tickness
    third_range = int(7.5 * GRID_UNIT) + tickness
    inner_p = (
        int(inner_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(inner_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    outer_p = (
        int(second_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(second_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, PALE_GRAY, thickness=2)
    # 時計の針の先
    # 楕円、描画する画像を指定、座標(x,y),xyの半径、角度,色、線の太さ(-1は塗りつぶし)
    cv2.ellipse(canvas,
                circle_rail.center, (second_range, second_range),
                -90,
                int(circle_rail.theta - outer_circle.unit_arc / 2),
                int(circle_rail.theta + outer_circle.unit_arc / 2),
                PALE_GRAY,
                thickness=tickness)
    cv2.ellipse(canvas,
                circle_rail.center, (third_range, third_range),
                -90,
                int(circle_rail.theta - outer_circle.unit_arc / 2),
                int(circle_rail.theta + outer_circle.unit_arc / 2),
                PALE_GRAY,
                thickness=tickness)
    #

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

    # 色成分数
    bar_box.draw_rgb_number(canvas, rank23d_color)

    # debug
    cv2.putText(
        canvas,
        f"triangle_theta={triangle_theta} phase={phase}",
        (10, 10),  # x,y
        cv2.FONT_HERSHEY_SIMPLEX,
        FONT_SCALE,
        BLACK,
        lineType=2)
    # f"multiple=({n3bars_multiple[0]:7.3f}, {n3bars_multiple[1]:7.3f}, {n3bars_multiple[2]:7.3f})",
    # f"zoom={circle_rail.zoom}",
    #               # f"delta_color=({delta_color[0]}, {delta_color[1]}, {delta_color[2]})",
    #               f"delta_3bars_height=({bar_box.delta_3bars_height[0]}, \
    # {bar_box.delta_3bars_height[1]}, \
    # {bar_box.delta_3bars_height[2]})",

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas
コード例 #8
0
def draw_canvas(canvas, bar_box, circle_rail, inner_circle, outer_circle):
    """アニメの1コマを作成します"""

    circle_rail.draw_me(canvas)  # 円レール

    circle_rail.draw_red_p(canvas)  # 円周上の点R
    circle_rail.draw_green_p(canvas)  # 円周上の点G
    circle_rail.draw_blue_p(canvas)  # 円周上の点B

    # 円に内接する線。三角形
    cv2.line(canvas,
             circle_rail.red_p,
             circle_rail.green_p,
             BLACK,
             thickness=2)
    cv2.line(canvas,
             circle_rail.green_p,
             circle_rail.blue_p,
             BLACK,
             thickness=2)
    cv2.line(canvas, circle_rail.blue_p, circle_rail.red_p, BLACK, thickness=2)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    a_color = convert_3heights_to_3bytes(bar_box.addition_3bars_height,
                                         bar_box.height)
    step1_color = convert_3heights_to_3bytes(
        bar_box.create_step1_3bars_height(), bar_box.height)
    rank3_byte = convert_height_to_byte(bar_box.height3, bar_box.height)
    rank23_color = convert_3heights_to_3bytes(
        bar_box.create_rank23_3bars_height(), bar_box.height)
    rank23a_color = convert_3heights_to_3bytes(
        bar_box.create_rank23a_3bars_height(), bar_box.height)
    # 3色成分(配色)
    a_3colors = (DARK_RED, DARK_GREEN, DARK_BLUE)
    step1_3colors = (VIVID_RED, VIVID_GREEN, VIVID_BLUE)
    rank3_3colors = (BRIGHT_RED, BRIGHT_GREEN, BRIGHT_BLUE)
    rank23a_3colors = (RED, GREEN, BLUE)

    #    # (WIP) 成分から角度を逆算
    #    element_rates, expected_theta = calc_color_element_rates(rank23_color)
    #    if circle_rail.theta != expected_theta:
    #        print(
    #            f"theta={circle_rail.theta:>7.3f}~{expected_theta:>7.3f} \
    # color_element(rank23_color)=({element_rates[0]:>7.3f}, \
    # {element_rates[1]:>7.3f}, \
    # {element_rates[2]:>7.3f})")
    bar_box.draw_3bars(canvas, a_3colors, step1_3colors,
                       rank3_3colors)  # RGBバー

    # プラス記号
    color_example_width = int(1.5 * GRID_UNIT)
    color_example_left = int(bar_box.left - 1.5 * color_example_width)

    # 色見本 23a
    left_top = (color_example_left, int(bar_box.bottom + int(2.5 * GRID_UNIT)))
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23a_color,
                  thickness=-1)  # 色見本

    # 色見本 rank23
    left_top = (color_example_left, int(bar_box.bottom + 3.75 * GRID_UNIT))
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23_color,
                  thickness=-1)  # 色見本

    bar_box.draw_y_axis_label(canvas)  # バー率テキスト

    # 時計の針
    clock_hand_len = int(4.5 * GRID_UNIT)
    inner_p = (int(circle_rail.range *
                   math.cos(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[0]),
               int(circle_rail.range *
                   math.sin(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[1]))
    outer_p = (int((circle_rail.range + clock_hand_len) *
                   math.cos(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[0]),
               int((circle_rail.range + clock_hand_len) *
                   math.sin(math.radians(circle_rail.theta - 90)) +
                   circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, LIGHT_GRAY, thickness=2)

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    cv2.line(canvas,
             circle_rail.red_p,
             (bar_box.step1_rect[0].right_bottom[0], circle_rail.red_p[1]),
             step1_3colors[0],
             thickness=2)

    # 水平線G
    cv2.line(canvas,
             circle_rail.green_p,
             (bar_box.step1_rect[1].right_bottom[0], circle_rail.green_p[1]),
             step1_3colors[1],
             thickness=2)

    # 水平線B
    cv2.line(canvas,
             circle_rail.blue_p,
             (bar_box.step1_rect[2].right_bottom[0], circle_rail.blue_p[1]),
             step1_3colors[2],
             thickness=2)

    inner_circle.draw_me(canvas)  # 内環状
    outer_circle.draw_me(canvas)  # 外環状

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

    # 色成分数
    bar_box.draw_rgb_number(canvas, a_color, a_3colors, step1_color,
                            step1_3colors, rank3_byte, rank23_color,
                            rank23a_color, rank23a_3colors)

    # cv2.imshow('Title', canvas)
    # cv2.imwrite('form.jpg',canvas)
    # cv2.waitKey(0)
    # cv2.destroyAllWindows()
    return canvas
コード例 #9
0
def draw_canvas(canvas, bar_box, circle_rail, inner_circle, outer_circle):
    """アニメの1コマを作成します"""

    circle_rail.draw_me(canvas)  # 円レール

    circle_rail.draw_red_p(canvas)  # 円周上の点R
    circle_rail.draw_green_p(canvas)  # 円周上の点G
    circle_rail.draw_blue_p(canvas)  # 円周上の点B

    # 円に内接する線。三角形
    cv2.line(canvas,
             circle_rail.red_p,
             circle_rail.green_p,
             WHITE,
             thickness=2)
    cv2.line(canvas,
             circle_rail.green_p,
             circle_rail.blue_p,
             WHITE,
             thickness=2)
    cv2.line(canvas, circle_rail.blue_p, circle_rail.red_p, WHITE, thickness=2)

    # 1色成分 (高さから 255 へ丸めるとき、誤差が出る)
    delta_color = convert_3heights_to_3bytes(bar_box.delta_3bars_height,
                                             bar_box.height)
    step1_color = convert_3heights_to_3bytes(
        bar_box.create_step1_3bars_height(), bar_box.height)
    rank3_byte = convert_height_to_byte(bar_box.height3, bar_box.height)
    rank23_color = convert_3heights_to_3bytes(
        bar_box.create_rank23_3bars_height(), bar_box.height)
    rank23d_color = convert_3heights_to_3bytes(
        bar_box.create_rank23a_3bars_height(), bar_box.height)
    # 3色成分(配色)
    delta_3colors = (DARK_RED, DARK_GREEN, DARK_BLUE)
    step1_3colors = (VIVID_RED, VIVID_GREEN, VIVID_BLUE)
    rank3_3colors = (BRIGHT_RED, BRIGHT_GREEN, BRIGHT_BLUE)

    #    # (WIP) 成分から角度を逆算
    #    element_rates, expected_theta = calc_color_element_rates(rank23_color)
    #    if circle_rail.theta != expected_theta:
    #        print(
    #            f"theta={circle_rail.theta:>7.3f}~{expected_theta:>7.3f} \
    # color_element(rank23_color)=({element_rates[0]:>7.3f}, \
    # {element_rates[1]:>7.3f}, \
    # {element_rates[2]:>7.3f})")
    bar_box.draw_3bars(canvas, delta_3colors, step1_3colors,
                       rank3_3colors)  # RGBバー

    bar_box.draw_y_axis_label(canvas)  # バー率テキスト

    color_example_width = int(1.5 * GRID_UNIT)
    left = bar_box.left - 2 * color_example_width
    swing_bar_width = int(0.75 * color_example_width)
    right = left + swing_bar_width
    color_example_left = int(left - color_example_width)
    # 最大値
    upper_bound_y = circle_rail.upper_bound_y()
    # 最小値
    lower_bound_y = circle_rail.lower_bound_y()
    # 色見本 23a
    left_top = (bar_box.left - color_example_width,
                bar_box.top2 - color_example_width)
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23d_color,
                  thickness=-1)  # 色見本

    # 正三角形の振動を表示
    # inner
    cv2.rectangle(canvas, (left, upper_bound_y), (right, lower_bound_y),
                  WHITE,
                  thickness=-1)
    cv2.rectangle(canvas, (left, lower_bound_y), (right, bar_box.bottom),
                  BRIGHT_GRAY,
                  thickness=-1)
    # diameter
    left = bar_box.left - color_example_width
    cv2.rectangle(canvas, (left, bar_box.top2),
                  (left + swing_bar_width, bar_box.top3),
                  BLACK,
                  thickness=-1)
    cv2.rectangle(canvas, (left, bar_box.top3),
                  (left + swing_bar_width, bar_box.bottom),
                  BRIGHT_GRAY,
                  thickness=-1)

    # 色見本 rank23
    left_top = (color_example_left + color_example_width,
                int(upper_bound_y - color_example_width))
    right_bottom = (left_top[0] + color_example_width,
                    left_top[1] + color_example_width)
    cv2.rectangle(canvas, left_top, right_bottom, rank23_color,
                  thickness=-1)  # 色見本

    # 水平線R
    # 線、描画する画像を指定、座標1点目、2点目、色、線の太さ
    if delta_color[0] > -1:
        line_color = step1_3colors[0]
    else:
        line_color = delta_3colors[0]
    cv2.line(canvas,
             circle_rail.red_p,
             (bar_box.step1_rect[0].right_bottom[0], circle_rail.red_p[1]),
             line_color,
             thickness=2)

    # 水平線G
    if delta_color[1] > -1:
        line_color = step1_3colors[1]
    else:
        line_color = delta_3colors[1]
    cv2.line(canvas,
             circle_rail.green_p,
             (bar_box.step1_rect[1].right_bottom[0], circle_rail.green_p[1]),
             line_color,
             thickness=2)

    # 水平線B
    if delta_color[2] > -1:
        line_color = step1_3colors[2]
    else:
        line_color = delta_3colors[2]
    cv2.line(canvas,
             circle_rail.blue_p,
             (bar_box.step1_rect[2].right_bottom[0], circle_rail.blue_p[1]),
             line_color,
             thickness=2)

    inner_circle.draw_me(canvas)  # 内環状
    outer_circle.draw_me(canvas)  # 外環状

    # 時計の針
    inner_range = circle_rail.range
    second_range = int(5.5 * GRID_UNIT)
    third_range = int(6.5 * GRID_UNIT)
    fourth_range = int(7.5 * GRID_UNIT)
    inner_p = (
        int(inner_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(inner_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    outer_p = (
        int(second_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(second_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, PALE_GRAY, thickness=2)
    #
    inner_p = (
        int(second_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(second_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    outer_p = (
        int((third_range) * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int((third_range) * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, WHITE, thickness=2)
    #
    inner_p = (
        int(third_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(third_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    outer_p = (
        int(fourth_range * math.cos(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[0]),
        int(fourth_range * math.sin(math.radians(circle_rail.theta - 90)) +
            circle_rail.center[1]))
    cv2.line(canvas, inner_p, outer_p, BLACK, thickness=2)
    #

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

    # 色成分数
    bar_box.draw_rgb_number(canvas, delta_color, step1_color, rank3_byte,
                            rank23d_color)

    # debug
    # cv2.putText(canvas,
    #            # f"delta_color=({delta_color[0]}, {delta_color[1]}, {delta_color[2]})",
    #            f"delta_3bars_height=({bar_box.delta_3bars_height[0]}, \
    # {bar_box.delta_3bars_height[1]}, \
    # {bar_box.delta_3bars_height[2]})",
    #            (10, 10),  # x,y
    #            cv2.FONT_HERSHEY_SIMPLEX,
    #            FONT_SCALE,
    #            BLACK,
    #            lineType=2)

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