如何为每个象限创建一个带有圆形末端的圆

编程入门 行业动态 更新时间:2024-10-14 16:20:55
本文介绍了如何为每个象限创建一个带有圆形末端的圆的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我创建了一个圆,该圆分为多个象限.我试图使每个象限的末端四舍五入,每个象限之间有给定的间隙,但是却出现了一些奇怪的现象.我想我缺少了一些东西.下面是我所得到的图像和相关代码.我希望它们的末端与Apple Watch活动环的末端相似.

I have created a circle that is divided into quadrants. I am trying to make the ends of each quadrant rounded with a given gap between each quadrant, but I get some strange behavior. I guess I'm missing something. Below is an image of what I'm getting and the relevant code. I want the ends to be similar to that of the Apple Watch activity ring.

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, startAngle: outerStartAngle, endAngle: outerEndAngle, clockwise: false) path.addArc(center: center, radius: innerRadius, startAngle: innerStartAngle, endAngle: innerEndAngle, clockwise: false) path.closeSubpath() return path }

推荐答案

这是另一组代码,其中生成的路径具有圆角末端,但是每个弧段都是填充的路径,而不是单个描边的线段.这应该允许路径发生碰撞而不会使端盖重叠.

Here's another set of code where the paths that are generated have rounded ends, but each arc segment is a filled path rather than being a single stroked segment. This should allow the paths to have collisions without the end caps overlapping.

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, strokeWidth: 18, 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, 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 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, radius: outerRadius, startAngle: outerStartAngle, endAngle: outerEndAngle, clockwise: true) path.addArc(center: rightEndCapPoint, radius: halfStrokeWidth, startAngle : 0, endAngle : CGFloat.pi, clockwise: true) path.addArc(center: CGPoint.zero, radius: innerRadius, startAngle: innerStartAngle, endAngle: innerEndAngle, clockwise: false) path.addArc(center: leftEndCapPoint, radius: halfStrokeWidth, startAngle : 3.0 * CGFloat.pi / 2.0, endAngle : CGFloat.pi / 2.0, clockwise: true) path.closeSubpath() return path }

更多推荐

如何为每个象限创建一个带有圆形末端的圆

本文发布于:2023-10-23 05:22:13,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1519912.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:象限   创建一个   圆形   何为

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!