LoginSignup
2
1

Julia の SymPy で書いてみました:中学入試レベル平面図形「意外と難しい角度問題(youtube)」

Last updated at Posted at 2024-05-25

以下の記事にある問題を Julia の SymPy で解いてみました。

他にも,いろいろな算額の問題をたくさん解いています。 https://blog.goo.ne.jp/r-de-r
今回の問題は,その応用問題みたいなものです。


赤の補助線を引く。
求める角度は水平線と赤線の角度から,水平線と緑線の角度を引いたもの。
atand(2) - atand(1/3) これは 45(度) になる。

ビデオにあるように,もう一本補助線を引いてもよいが,それでは SymPy を使うメリットがない。

プログラムは長いですが,図形を書くためのもので,胆は
theta = atand(2) - atand(1/3)
だけです。

using Plots

function segment(x1, y1, x2, y2, color=:black; linestyle=:solid, lw=0.5)
    plot!([x1, x2], [y1, y2], color=color; linestyle=linestyle, lw=lw)
end;

function point(x, y, string="", color=:green, position=:left, vertical=:top; mark=true, delta=0, deltax=0)
    mark && scatter!([x], [y], color=color, markerstrokewidth=0, markersize=3)
    annotate!(x + deltax, y + delta, text(string, 10, position, color, vertical))
end;

function draw(more=false)
    pyplot(size=(500, 500), grid=false, aspectratio=1, label="", fontfamily="IPAMincho")
    a = 1
    plot([0, a, a, 0, 0], [0, 0, a, a, 0], color=:blue, lw=0.5)
    plot!([0, a/2, a], [0, a, 0], color=:blue, lw=0.5)
    segment(0, a/2, 3a/2,0, :green)
    segment(a, a, 3a/2, 0, :red)
    theta = atand(2) - atand(1/3)
    println(theta)
    if more        
        delta = (fontheight = (ylims()[2]- ylims()[1]) / 500 * 10 * 2) /3  # size[2] * fontsize * 2
        hline!([0], color=:gray80, lw=0.5)
        vline!([0], color=:gray80, lw=0.5)
        point(0, a/2, " a/2", :blue, :left, :bottom, delta=delta/2)
        point(a, 0, " a", :blue, :left, :bottom, delta=delta/2)
        point(3a/2, 0, " 3a/2", :blue, :left, :bottom, delta=delta/2)
        point(a/2, a, "(a/2,a)", :blue, :center, :bottom, delta=delta/2)
    end
end;

draw(true)

fig1.png

ChatGPT に,「Python に書き直して!」と頼むと以下のようにしてくれた。
描画のためのサブプログラムを matplotlib で書いているので,ちょっと冗長。
 point() は機能していない。

import matplotlib.pyplot as plt
import numpy as np

def segment(x1, y1, x2, y2, color='black', linestyle='-', lw=0.5):
    plt.plot([x1, x2], [y1, y2], color=color, linestyle=linestyle, linewidth=lw)

def point(x, y, string="", color='green', position='left', vertical='top', mark=True, delta=0, deltax=0):
    if mark:
        plt.scatter([x], [y], color=color, s=10, zorder=5)
    if position == 'left':
        horizontalalignment = 'right'
    elif position == 'right':
        horizontalalignment = 'left'
    else:
        horizontalalignment = 'center'
        
    if vertical == 'top':
        verticalalignment = 'bottom'
    elif vertical == 'bottom':
        verticalalignment = 'top'
    else:
        verticalalignment = 'center'
    
    plt.annotate(string, (x + deltax, y + delta), textcoords="offset points", xytext=(0,0), ha=horizontalalignment, va=verticalalignment, fontsize=10, color=color)

def draw(more=False):
    plt.figure(figsize=(5, 5))
    a = 1
    plt.plot([0, a, a, 0, 0], [0, 0, a, a, 0], color='blue', linewidth=0.5)
    plt.plot([0, a/2, a], [0, a, 0], color='blue', linewidth=0.5)
    segment(0, a/2, 3*a/2, 0, color='green')
    segment(a, a, 3*a/2, 0, color='red')
    theta = np.degrees(np.arctan(2) - np.arctan(1/3))
    print(theta)
    
    if more:
        delta = 10 / 3  # Adjust the delta value as needed
        plt.axhline(0, color='gray', linestyle='--', linewidth=0.5)
        plt.axvline(0, color='gray', linestyle='--', linewidth=0.5)
        point(0, a/2, " a/2", color='blue', position='left', vertical='bottom', delta=delta/2)
        point(a, 0, " a", color='blue', position='left', vertical='bottom', delta=delta/2)
        point(3*a/2, 0, " 3a/2", color='blue', position='left', vertical='bottom', delta=delta/2)
        point(a/2, a, "(a/2,a)", color='blue', position='center', vertical='bottom', delta=delta/2)
    
    plt.grid(False)
    plt.gca().set_aspect('equal', adjustable='box')
    plt.show()

draw(True)
2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1