在CGPath上获取随机的CGPoint [英] Get random CGPoint on CGPath
问题描述
我有一个表示椭圆的CGPath.我想将一个Sprite节点放置在该路径上的一个随机点上.如何在该CGPath上获得随机的CGPoint?
I have a CGPath that represents an ellipse. I'd like to place a sprite node at a random point on that path. How can I get a random CGPoint on that CGPath?
推荐答案
谈论封闭的 CGPath
,并思考一种快速方法,以获取 CGPath内部无限点之间的随机点
,首先我已将其翻译为 Swift :
Speaking about a closed CGPath
and thinking to a fast method to obtain a random point between infinite points inside a CGPath
, first of all I've translated to Swift this:
extension CGPath {
func forEach(@noescape body: @convention(block) (CGPathElement) -> Void) {
typealias Body = @convention(block) (CGPathElement) -> Void
func callback(info: UnsafeMutablePointer<Void>, element: UnsafePointer<CGPathElement>) {
let body = unsafeBitCast(info, Body.self)
body(element.memory)
}
//print(sizeofValue(body))
let unsafeBody = unsafeBitCast(body, UnsafeMutablePointer<Void>.self)
CGPathApply(self, unsafeBody, callback)
}
func getPathElementsPoints() -> [CGPoint] {
var arrayPoints : [CGPoint]! = [CGPoint]()
self.forEach { element in
switch (element.type) {
case CGPathElementType.MoveToPoint:
arrayPoints.append(element.points[0])
case .AddLineToPoint:
arrayPoints.append(element.points[0])
case .AddQuadCurveToPoint:
arrayPoints.append(element.points[0])
arrayPoints.append(element.points[1])
case .AddCurveToPoint:
arrayPoints.append(element.points[0])
arrayPoints.append(element.points[1])
arrayPoints.append(element.points[2])
default: break
}
}
return arrayPoints
}
func spriteKitCenter() ->CGPoint {
let shape = SKShapeNode(path: self)
return CGPointMake(CGRectGetMidX(shape.frame),CGRectGetMidY(shape.frame))
}
func uiKitCenter() ->CGPoint {
let layer = CAShapeLayer()
layer.path = self
return CGPointMake(CGRectGetMidX(layer.frame),CGRectGetMidY(layer.frame))
}
}
我对不规则多边形使用了following方法,该方法基于三角形,因此,如果使用圆弧,则会丢失一些曲线部分(请提供建议,我将不胜感激):
I used the follow method with my irregulars polygon, it's based on triangles so if you use arcs some curve parts will be losts (please if you have any advice comment it, I'd be grateful):
- 获取所有
CGPath
边界点(组成我的路径的元素) - 获取我的
CGPath
的中心 - 获取我的点和中心之间的三角形列表
- 从三角形列表中选择一个随机三角形
- 在三角形内选择一个随机点
- get all
CGPath
border points (element that compose my path) - get the center of my
CGPath
- obtain a list of triangles between my points and the center
- choose a random triangle from the triangles list
- choose a random point inside the triangle
这是三角形方法:
func getRandomPointInTriangle (aPoint:CGPoint,bPoint:CGPoint,cPoint:CGPoint)->CGPoint {
var randomA = CGFloat(Float(arc4random()) / Float(UINT32_MAX))
var randomB = CGFloat(Float(arc4random()) / Float(UINT32_MAX))
if (randomA + randomB > 1) {
randomA = 1-randomA
randomB = 1-randomB
}
let randomC = 1-randomA-randomB
let rndX = (randomA*aPoint.x)+(randomB*bPoint.x)+(randomC*cPoint.x)
let rndY = (randomA*aPoint.y)+(randomB*bPoint.y)+(randomC*cPoint.y)
return CGPointMake(rndX,rndY)
}
这是主要方法:
func getRandomPoint()->CGPoint {
let points = self.path!.getPathElementsPoints()
let center = self.path!.spriteKitCenter()
// divide the cgpath in triangles
var triangles = Array<Array<CGPoint>>()
for i in 0..<points.count-1 {
let triangle = [center,points[i],points[i+1]]
triangles.append(triangle)
}
let chooseTriangleNum = Int(arc4random()) % triangles.count
let chooseTriangle = triangles[chooseTriangleNum]
return getRandomPointInTriangle(chooseTriangle[0],bPoint: chooseTriangle[1],cPoint: chooseTriangle[2])
}
这篇关于在CGPath上获取随机的CGPoint的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!