八木日記

いろいろなこと

単位円を使って角度がわかるやつをelmでつくった

知りたい角度を入力すると、その角度の扇型が表示されるやつを
elmでつくった

画面はこんな感じ
f:id:ygnb0605:20191125221701p:plain

テキストボックスに任意の角度を入力して「角度計算」ボタンを押すと
青い扇型がその角度になる
f:id:ygnb0605:20191125221848p:plain

360度をこえると、こんな感じになって0度からの表示と同様になる
390度の場合、390-360=30なので30度と同じ
f:id:ygnb0605:20191125222145p:plain


ちなみに、クリアボタンを押すと初期状態と同じく
90度になる

ソースコードは以下の通り

import Browser
import Svg exposing (..)
import Svg.Attributes exposing (width, height, viewBox, d, fill, x, y, r, rx, ry)
import Svg.PathD exposing (..)
import Html exposing (Html, button, div, input, Attribute, text)
import Html.Attributes exposing (value, placeholder)
import Html.Events exposing (onClick, onInput)

main = Browser.sandbox { init = init, update = update, view = view }

type Msg = Input String | Clear | Calc

type alias Model =
    {
      xLength : Float
      , yLength : Float
      , degreeCircle : String
    }

init : Model
init =
    { xLength = 300
    , yLength = 200
    , degreeCircle = ""
    }


update : Msg -> Model -> Model
update msg model  =
  case msg of
    Input input ->
     { model | degreeCircle = input }
    Calc ->
     {
       xLength = 200 + (100 * cos(degrees ( 90 - Maybe.withDefault 0 (String.toFloat model.degreeCircle))))
      , yLength = 200 - (100 * sin(degrees ( 90 - Maybe.withDefault 0 (String.toFloat model.degreeCircle))))
      , degreeCircle = model.degreeCircle
     }
    Clear ->
     {
       xLength = 300
      , yLength = 200
      , degreeCircle = ""
     }


view model =
  div[]
  [
    svg
     [ width "500"
       , height "500"
       , viewBox "0 0 500 500"
     ]
     [ Svg.path
        [ d <| pathD
            [ M (200, 200)
            , L (200, 100)  
            , A (100, 100)  0 False True (model.xLength, model.yLength ) 
            , Z
            ]
            , fill "blue"
        ]
        []
     ] 
     , input [ placeholder "角度入力", onInput Input] []
     , button [ onClick Calc] [ text "角度計算"]
     , button [ onClick Clear] [ text "クリア"]
  ]

単位円の中心を(200,200)にして、扇型を作成した
作成する扇型のx座標とy座標はそれぞれ以下の式で求めた
x座標 = 中心のx座標 + 単位円の半径 × cos(90 - 入力した角度 )
y座標 = 中心のy座標 - 単位円の半径 × sin(90 - 入力した角度 )