在CGPath上获取随机的CGPoint [英] Get random CGPoint on CGPath

查看:87
本文介绍了在CGPath上获取随机的CGPoint的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个表示椭圆的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆