フリープログラマー日記

iOS,アンドロイド開発を気ままにしながら生きてるおじさんのブログです。

第6回 swift で お絵描き!

前回の続きです。
と言っても、少し寄り道ですが、swift でお絵描きをする方法の紹介です。
ま、あちこちにたくさん情報があるので、新しくはないですが。

考えたのは、次のような直線と半円を繋いだ線を描くこと。

f:id:momonga117:20180506223057p:plain

画面のセンターから、左右に 'a' だけ離れたところに、半径 'r' の半円を描くというものです。

    
    func track() {
        
        // 陸上トラック、青色、線5本を描く
        let a: CGFloat = viewWidth * 0.17        // 直線の長さの半分
        let r: CGFloat = viewWidth * 0.19        // 半径
        let lineWidth: CGFloat = viewWidth * 0.002        // 線幅
    
        
        // コンテキストの取得
        let context = UIGraphicsGetCurrentContext()
        
        // 線幅をセット
        context?.setLineWidth(lineWidth)
    
        // 描画色を青色にセット
        context?.setStrokeColor(UIColor.blue.cgColor)
        
        
        // 横線を引く
        context?.move(to: CGPoint(x: viewWidth/2 - a, y: viewHeight/2 - r))
        context?.addLine(to: CGPoint(x: viewWidth/2 + a, y: viewHeight/2 - r))
        context?.move(to: CGPoint(x: viewWidth/2 - a, y: viewHeight/2 + r))
        context?.addLine(to: CGPoint(x: viewWidth/2 + a, y: viewHeight/2 + r))
        
        // 左右の半円
        let leftCenter: CGPoint = CGPoint(x: viewWidth/2 - a, y: viewHeight/2)
        let rightCenter: CGPoint = CGPoint(x: viewWidth/2 + a, y: viewHeight/2)
        let circleTopAngle = CGFloat(3.141592/2)
        let circleBottomAngle = CGFloat(3.141592/2*3)
        context?.addArc(center: leftCenter, radius: r, startAngle: circleTopAngle, endAngle: circleBottomAngle, clockwise: false)
        context?.addArc(center: rightCenter, radius: r, startAngle: circleBottomAngle, endAngle: circleTopAngle, clockwise: false)

        
        // 描画を実行する
        context?.strokePath()
        
    }

前回の MainMenu.swift に追加しました。

コンテキストを取得して、2本の直線と2個の半円を描いているだけです。コンテキストの使い方はこれでいいのかと思いますが、とりあえず解説すると、move と addLine で一本の直線、addArc で円弧を描いています。私なりの解釈では、コンテキストは設計図みたいなものじゃないかと思っています。説明書には構造体やらなんやら・・・むにゃむにゃ

clockwise: false にしないと、数学のラジアンと同じ向きにならないので気をつけて下さいね。

で、実行したのがこちら。

f:id:momonga117:20180508200615p:plain

内周近くに新しい線が入りました。
まだ1本ですが、あと4本は、同じようにかけるはず。

実は、これ、関数にしてますが、そのわけは半径を変えて5回呼ぶのがいいのか、for ループ の中に入れてしまうのがいいのか・・・

そんなん、好きな方にしろよと言われそうな問題なんでしょうね。

考慮時間5分で、半径を引数とする関数に変えることにしました。

    func track(r: CGFloat) {
        
        // 陸上トラック、青色、線5本を描く
        let a: CGFloat = viewWidth * 0.17        // 直線の長さの半分
        //let r: CGFloat = viewWidth * 0.19        // 半径

半径 r を引数で渡し、もとの半径の部分はコメントアウトに。

呼び出し側はこんな風にループにしました。

        
        for i:CGFloat in [0.0,1.0,2.0,3.0,4.0] {
            track(r: viewWidth * (0.19 + 0.02*i))
        }
       

I をint にしたら当然怒られました。

実行すると左のように。
もとのビットマップの表示をやめたのが右側。


f:id:momonga117:20180508203758p:plain

MainMenu ビューがわかるように黄色にしてたのですが、ビットマップがなくなったので、次からは白に戻します。

次回は、Android で同じことをしてみます。