四、ARKit涂鸦②

欢迎小伙伴们的到来~

(一)介绍

如果小伙伴们还没对ARKit有任何的了解可以先看看我前面几章的介绍再来更好的看本章内容

一、ARKit初探索

二、SCNGeometry代码创建几何体

三、ARKit涂鸦①

本次的代码已上传 github

终于有时间来继续更新文章~~~

上一次给大家简单的介绍了一下使用SCNGeometry在平面上绘制线条的方法,但是SCNGeometry无法设置线条的宽度,为了使我们绘制出来的线条圆滑一些,我决定使用SCNGeometry绘制圆柱来代表线条,圆柱的直径就是线条的宽度。

本次我还在其中加入了撤销、更改颜色、更改线条宽度等功能

先看下本次分享东西的效果图

1.gif

(二)开始~

首先我们来看一张图片

四、ARKit涂鸦②_第1张图片
QQ20171119-110029.png

图片来自

从上图我们可以看到要绘制一个圆柱,可以使用逐步逼近法,用一个个长方形拼合来逐步逼近圆,这里我们使用两个三角形组合一个长方形。
1.获取屏幕上手指划过的位置相对真实世界对象的位置

2.拿到本次屏幕上划过的位置,计算出两点间圆柱上长方形的所有顶点。

3.然后使用SCNGeometry绘制三角扇链接所有顶点。

下面我们就来实现所有的步骤:

1. 获取屏幕上手指划过的位置相对真实世界对象的位置

实现步骤

详细见上一章ARKit涂鸦①

或查看代码 github (MQARSCNController+AddNode.swift -> touchesMoved())

2.拿到本次屏幕上划过的位置,计算出两点间圆柱上长方形的所有顶点

关键代码,具体查看项目MQNode类中addVertices方法

四、ARKit涂鸦②_第2张图片
2-1
    //将圆分成40等份,迭代出当前点对应的圆所有顶点
    for index in 0...40 {
        
        //计算本次[弧度](https://baike.baidu.com/item/%E5%BC%A7%E5%BA%A6/1533188?fr=aladdin),360°角=2π弧度,分成40份
        let t = Double(index) * (Double.pi * 2 / 40)
        
        //计算当前点对应的圆所有顶点
        let s = atan(-(Double(previousVertice.x)*cos(t) + Double(previousVertice.y)*sin(t)) / Double(previousVertice.z))
        let xt = Double(currenVertice.x) + r * cos(s) * cos(t)
        let yt = Double(currenVertice.y) + r * cos(s) * sin(t)
        let zt = Double(currenVertice.z) + r * sin(s)
        
        let ver = SCNVector3Make(Float(xt), Float(yt), Float(zt))
        
        //保存本次所有顶点,用于和下次的点进行连接
        tempPreviousVertices.append(ver)
        
        /*
            -------上次点
            ||||||| 一一对应添加
            -------本次点
            如2-1图所示
        */
        //添加本次点        
        roundLineVertices.append(ver)
        //添加上次对应点 
        roundLineVertices.append(roundPreviousVertices[index])
        
        //添加顶点索引
        let verticesCount = UInt32(roundLineVertices.count)
        roundLineIndices.append(verticesCount-2)
        roundLineIndices.append(verticesCount-1)
    }

3.然后使用SCNGeometry绘制三角扇链接所有顶点。

关键代码,具体查看项目MQNode类中addVertices方法

    //创建SCNGeometry
    let geometry = SCNGeometry(sources: [SCNGeometrySource(vertices: roundLineVertices)], elements: [SCNGeometryElement(indices: roundLineIndices, primitiveType: .triangleStrip)])
    
    //创建渲染器        
    let material = SCNMaterial()
    material.isDoubleSided = true
    material.diffuse.contents = MQARSCNController.sharedInstance.linecolour

    geometry.firstMaterial = material
    
    //把本次的圆柱添加到node上
    let node = SCNNode(geometry: geometry)
    self.addChildNode(node)

本章内容就到这里感谢小伙伴们的到来~
代码已经上传github

你可能感兴趣的:(四、ARKit涂鸦②)