iOS:ApplePencilに触れてみる

iPadProを購入してApplePencilも購入した。
使いごこちはなかなかの物。

ApplePencilを使ったアプリってどうやって作るのかと思い

チュートリアル的なものは何かないかと探したところ下記サイトを見つけた。
                       ⬇︎
https://www.raywenderlich.com/121834/apple-pencil-tutorial

※英語ダメダメなので間違っている可能性大かもしれません。

Download and explore Scribble.をクリックするとチュートリアルで使うプロジェクトを落としてこれる。

このプロジェクトを実行してみると何の変哲もない線が描けるらしい。
![IMG_0027.PNG](https://qiita-image-store.s3.amazonaws.com/0/84002/e209a840-d894-5c8a-5e58-c6770a6e76e7.png)

最初の項目：　筆圧によって線の太さを変える

```swift

private func lineWidthForDrawing(context: CGContext?, touch: UITouch) -> CGFloat {

    var lineWidth = defaultLineWidth
    
    if touch.force > 0 {
        lineWidth = touch.force * forceSensitivity
    }
    
    return lineWidth
  }
```
上記のメソッドに下記のように追加してやると筆圧によって線の太さが変わる

```
if touch.force > 0 {
  lineWidth = touch.force * Forcefulness
}
```
![IMG_0028.PNG](https://qiita-image-store.s3.amazonaws.com/0/84002/b54f9ccf-5459-244f-0fff-2f1c422e64a6.png)

次の項目：よりスームズに描画する

iPadProがタッチイベントをスキャンする時間は120秒だそうだ。
しかしiPadProはリフレッシュレートが60であることからそれを全部拾いきれないが為に
円などを書くと角質のある円になってしまう。
そこでPG側で送らてくる信号を整理しスムーズに書けるようにするというものらしい。（翻訳に自信なし）

```swift
drawStroke(context, touch: touch)
```
の部分を

```
var touches = [UITouch]()
    
    // 2
    if let coalescedTouches = event?.coalescedTouchesForTouch(touch) {
        touches = coalescedTouches
    } else {
        touches.append(touch)
    }
    
    // 3
    print(touches.count)
    
    // 4
    for touch in touches {
        drawStroke(context, touch: touch)
    }

```
というふうに置き換える。

変更する前の円
![IMG_0029.PNG](https://qiita-image-store.s3.amazonaws.com/0/84002/dac0bc1a-456c-ddd4-5a6e-05a5c9d45484.png)

変更後の円
![IMG_0030.PNG](https://qiita-image-store.s3.amazonaws.com/0/84002/666b35d4-0269-9ad1-b458-5224eaeb08e8.png)

遠目からではわかりにくいが目の錯覚でなければちゃんと変わっていると思う。（描くのが下手なだけでは・・・）

ちょっと頭がヒートしてきたので次で最後

最後は、ApplePencilの傾きを検知し角度によって描画方法を変える。

途中に　```pencilTexture.setStroke()``` とあります。

```drawColor.setStroke() ```を上記のように変えると
アセットで登録してある画像で線などが描けるようです。

```swift
private var pencilTexture = UIColor(patternImage: UIImage(named: "PencilTexture")!)
```
上記のように使う画像をセットしておきましょう。


そして本題


```swift

drawStroke(){
```
の中に下記のように追加

```swift
var lineWidth:CGFloat
    if touch.altitudeAngle < tiltThreshold {
        lineWidth = lineWidthForShading(context, touch: touch)
    } else {
        lineWidth = lineWidthForDrawing(context, touch: touch)
    }
```
新たに傾きを計算するメソッドを追加

```swift

 private func lineWidthForShading(context: CGContext?, touch: UITouch) -> CGFloat {
        
        // 1
        let previousLocation = touch.previousLocationInView(self)
        let location = touch.locationInView(self)
        
        // 2 - vector1 is the pencil direction
        let vector1 = touch.azimuthUnitVectorInView(self)
        
        // 3 - vector2 is the stroke direction
        let vector2 = CGPoint(x: location.x - previousLocation.x, y: location.y - previousLocation.y)
        
        // 4 - Angle difference between the two vectors
        var angle = abs(atan2(vector2.y, vector2.x) - atan2(vector1.dy, vector1.dx))
        
        // 5
        if angle > π {
            angle = 2 * π - angle
        }
        if angle > π / 2 {
            angle = π - angle
        }
        
        // 6
        let minAngle: CGFloat = 0
        let maxAngle = π / 2
        let normalizedAngle = (angle - minAngle) / (maxAngle - minAngle)
        
        // 7
        let maxLineWidth: CGFloat = 60
        var lineWidth = maxLineWidth * normalizedAngle
        
        return lineWidth
    }

```
実行結果を確認すると・・・
![IMG_0031.PNG](https://qiita-image-store.s3.amazonaws.com/0/84002/ea6c0f10-7d77-c077-f44a-863a7bfeaa96.png)
確かに傾けた部分に変化が！

なんかペンの傾きを使ったゲームかなんか作れたら面白そうだ。

頭が限界なのでこれにてお触り終了。