微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

swift – 如何为每个象限创建一个圆形末端的圆圈

我创建了一个分为象限的圆圈.我试图让每个象限的末端四舍五入,每个象限之间有一个给定的间隙,但我得到了一些奇怪的行为.我想我错过了一些东西.下面是我得到的图像和相关代码.我希望结局类似于Apple Watch活动环.

enter image description here

class GameScene: SKScene {

let radius = CGFloat(100)
var topRightPathNode : SKShapeNode!
var bottomrightPathNode : SKShapeNode!
var bottomLeftPathNode : SKShapeNode!
var topLeftPathNode : SKShapeNode!

override func didMove(to view: SKView) {

}


override init(size: CGSize) {
    super.init(size: size)
    let topRightPath = arcSegment(center: CGPoint.zero,radius: radius,strokeWidth: 18,gapWidth: 6)

    // TOP RIGHT


    topRightPathNode = SKShapeNode(path: topRightPath)
    topRightPathNode.fillColor = SKColor.white
    topRightPathNode.linewidth = 0
    topRightPathNode.position = CGPoint(x: 320,y: 240)
    addChild(topRightPathNode)


    // BottOM RIGHT

    var reflectOnY = CGAffineTransform(scaleX: 1.0,y: -1.0)
    let bottomrightPath = topRightPath.copy(using: &reflectOnY)!
    bottomrightPathNode = SKShapeNode(path: bottomrightPath)
    bottomrightPathNode.fillColor = SKColor.red
    bottomrightPathNode.linewidth = 0
    bottomrightPathNode.position = CGPoint(x: 320,y: 240)
   addChild(bottomrightPathNode)


    // BottOM LEFT


    //var reflectOnX = CGAffineTransform(scaleX: -1.0,y: 1.0)
    //let bottomLeftPath = bottomrightPath.copy(using: &reflectOnX)!
    var reflectOnXAndY = CGAffineTransform(scaleX: -1.0,y: -1.0)
    let bottomLeftPath = topRightPath.copy(using: &reflectOnXAndY)!

    bottomLeftPathNode = SKShapeNode(path: bottomLeftPath)
    bottomLeftPathNode.fillColor = SKColor.purple
    bottomLeftPathNode.linewidth = 0
    bottomLeftPathNode.position = CGPoint(x: 320,y: 240)
    addChild(bottomLeftPathNode)



    // TOP LEFT
    var reflectOnX = CGAffineTransform(scaleX: -1.0,y: 1.0)
    let topLeftPath = topRightPath.copy(using: &reflectOnX)!
    topLeftPathNode = SKShapeNode(path: topLeftPath)
    topLeftPathNode.fillColor = SKColor.cyan
    topLeftPathNode.linewidth = 0
    topLeftPathNode.position = CGPoint(x: 320,y:240)
    addChild(topLeftPathNode)

}

required init?(coder aDecoder: NSCoder) {
    fatalError("init(coder:) has not been implemented")
}


func arcSegment(center : CGPoint,radius: CGFloat,strokeWidth: CGFloat,gapWidth: CGFloat) -> CGPath
{
    let halfstrokeWidth = strokeWidth / 2.0
    let outerRadius = radius + halfstrokeWidth
    let innerRadius = radius - halfstrokeWidth
    let halfGap = gapWidth / 2.0

    let outerStartAngle = CGFloat(atan2(sqrt(outerRadius * outerRadius - halfGap * halfGap),halfGap))
    let outerEndAngle = CGFloat(atan2(halfGap,sqrt(outerRadius * outerRadius - halfGap * halfGap)))

    let innerStartAngle = CGFloat(atan2(halfGap,sqrt(innerRadius * innerRadius - halfGap * halfGap)))
    let innerEndAngle = CGFloat(atan2(sqrt(innerRadius * innerRadius - halfGap * halfGap),halfGap))

    let path = CGMutablePath()

    path.addArc(center: center,radius: outerRadius,startAngle: outerStartAngle,endAngle: outerEndAngle,clockwise: true)
    // Quartz 2D will assume a "moveto" here
    path.addArc(center: CGPoint(x: center.x + radius,y: center.y),radius: halfstrokeWidth,clockwise: false)

    path.addArc(center: center,radius: innerRadius,startAngle: innerStartAngle,endAngle: innerEndAngle,clockwise: false)

    path.closeSubpath()


    return path
}

解决方法

这是另一组代码,其中生成的路径具有圆形末端,但每个弧段是填充路径而不是单个描边段.这应该允许路径在没有端盖重叠的情况下发生碰撞.

import UIKit
import SpriteKit
import PlaygroundSupport

let radius = CGFloat(100)

let scenesize = CGSize(width: 640,height: 480)
let sceneView = SKView(frame: CGRect(origin: CGPoint.zero,size: scenesize))

let scene = SKScene(size: scenesize)
scene.backgroundColor = UIColor.black

let topRightPath = arcSegment(radius: radius,gapWidth: 25)

let topRightPathNode = SKShapeNode(path: topRightPath)
topRightPathNode.fillColor = SKColor.white
topRightPathNode.position = CGPoint(x: 320,y: 240)
topRightPathNode.linewidth = 0
scene.addChild(topRightPathNode)


var reflectOnY = CGAffineTransform(scaleX: 1.0,y: -1.0)
let bottomrightPath = topRightPath.copy(using: &reflectOnY)!
let bottomrightPathNode = SKShapeNode(path: bottomrightPath)
bottomrightPathNode.fillColor = SKColor.orange
bottomrightPathNode.position = CGPoint(x: 320,y: 240)
bottomrightPathNode.linewidth = 0
scene.addChild(bottomrightPathNode)


var reflectOnX = CGAffineTransform(scaleX: -1.0,y: 1.0)
let bottomLeftPath = bottomrightPath.copy(using: &reflectOnX)!
let bottomLeftPathNode = SKShapeNode(path: bottomLeftPath)
bottomLeftPathNode.fillColor = SKColor.green
bottomLeftPathNode.position = CGPoint(x: 320,y: 240)
bottomLeftPathNode.linewidth = 0
scene.addChild(bottomLeftPathNode)


let topLeftPath = bottomLeftPath.copy(using: &reflectOnY)!
let topLeftPathNode = SKShapeNode(path: topLeftPath)
topLeftPathNode.fillColor = SKColor.blue
topLeftPathNode.position = CGPoint(x: 320,y:240)
topLeftPathNode.linewidth = 0
scene.addChild(topLeftPathNode)

sceneView.presentScene(scene)

PlaygroundPage.current.liveView = sceneView
PlaygroundPage.current.needsIndefiniteExecution = true

func arcSegment( radius: CGFloat,halfGap))

    let leftEndAngle = CGFloat(atan2(sqrt(radius * radius - halfGap * halfGap),halfGap))

    let leftEndCapPoint = CGPoint(x: radius * cos(leftEndAngle),y: radius * sin(leftEndAngle))
    let rightEndCapPoint = CGPoint(x: leftEndCapPoint.y,y: leftEndCapPoint.x)


    let path = CGMutablePath()

    path.addArc(center: CGPoint.zero,clockwise: true)

    path.addArc(center: rightEndCapPoint,startAngle : 0,endAngle : CGFloat.pi,clockwise: true)

    path.addArc(center: CGPoint.zero,clockwise: false)

    path.addArc(center: leftEndCapPoint,startAngle : 3.0 * CGFloat.pi / 2.0,endAngle : CGFloat.pi / 2.0,clockwise: true)

    path.closeSubpath()

    return path
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐