📐

三角関数で三角形のアレを求める公式全部試す

2023/09/03に公開

事前の情報

a = V[400, 200]               # => (400, 200)
b = V[480, 61.4359353944898]  # => (480, 61.4359353944898)
ab = b - a                                    # => (80, -138.5640646055102)
ba = a - b                                    # => (-80, 138.5640646055102)
c = a + V[Math.cos(ab.angle) * ab.length, 0]  # => (480.0, 200)
d = a + V[0, Math.sin(ab.angle) * ab.length]  # => (400, 61.4359353944898)
ac = c - a                                    # => (80.0, 0)
cb = b - c                                    # => (0.0, -138.5640646055102)
bc = c - b                                    # => (0.0, 138.5640646055102)
斜辺 = ab.length       # => 160.0
底辺 = ac.length       # => 80.0
対辺 = bc.length       # => 138.5640646055102
角度 = -60.deg_to_rad  # => -1.0471975511965976

ここで上の4つのうち2つの情報しかないとしたとき公式から残りの一方が求められる。

sin

sinθ * 斜辺 → 対辺

sin(角度) * 斜辺  # => -138.56406460551017

対辺 / sinθ → 斜辺

対辺 / sin(角度)  # => -160.00000000000003

対辺 / 斜辺 → 角度

asin(対辺 / 斜辺).rad_to_deg  # => 60.00000000000001

cos

cosθ * 斜辺 → 底辺

cos(角度) * 斜辺  # => 80.00000000000001

底辺 / cosθ → 斜辺

底辺 / cos(角度)  # => 159.99999999999997

底辺 / 斜辺 → 角度

acos(底辺 / 斜辺).rad_to_deg  # => 59.99999999999999

tan

tanθ * 底辺 → 対辺

tan(角度) * 底辺  # => -138.56406460551014

対辺 / tanθ → 底辺

対辺 / tan(角度)  # => -80.00000000000003

対辺 / 底辺 → 角度

atan(対辺 / 底辺).rad_to_deg  # => 60.00000000000001
atan2(対辺, 底辺).rad_to_deg  # => 60.00000000000001

atan は半円分しか返ってこないのでちょっと使いづらい。そこで全方向に対応した atan2[1] が用意されている。

ところで atan2 にはなぜ引数を分けて渡さないといけないのだろうか? それは y / x をする前の値の符号を見て atan の結果に反映したいから。y / x の結果を渡されたのでは符号がわからず atan2 氏は困ってしまう。だから atan2 には y, x を分けて渡す。

コード
class App < Base
  include Math

  def initialize
    super

    self.width, self.height = V[800, 400]

    a = wh.center
    b = a + V.from_angle(-60.deg_to_rad) * wh.min_element * 0.4

    @points.concat([a, b])
  end

  def draw
    super

    a, b = @points

    ab = b - a
    c = a + V[cos(ab.angle) * ab.length, 0]
    d = a + V[0, sin(ab.angle) * ab.length]
    ac = c - a
    ad = d - a
    bc = c - b

    point_with_name_draw("a", a)
    point_with_name_draw("b", b)
    point_with_name_draw("c", c)

    vputs "斜辺ab: #{ab.length.round}"
    vputs "底辺ac: #{ac.length.round}"
    vputs "対辺bc: #{bc.length.round}"
    vputs "角度: #{ab.angle.rad_to_deg.round}"
    vputs "atan: #{atan(ab.y / ab.x).rad_to_deg.round}"

    arrow_head(a, b, "b")
    arrow_head(b, a, "a")
    arrow_head(b, c, "c")

    line_draw(a, b)
    line_draw(b, c)

    line_draw(V[0.0, a.y], V[wh.x, a.y])
    line_draw(V[a.x, 0.0], V[a.x, wh.y])

    point_draw(a, b, c)

    circle_draw(a, ab.length)
  end

  show
end
脚注
  1. もっとマシな名前をつけてほしかった ↩︎

Discussion