从两点创建大括号曲线 [英] Creating a curly bracket curve from two points

查看:98
本文介绍了从两点创建大括号曲线的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图从两个方面在Swift中创建大括号.这个想法可以很好地保持直线,因为它无论如何目前都不是动态的.我的问题在于根据p1和p2点的位置找到动态控制点和中心.

I'm trying to create a curly bracket in Swift, from two points. The idea works fine, with a straight line, because it's currently not dynamic in anyway. My issue lies in finding the dynamic control points and center depending on the location of p1 and p2 points.

这是我当前的代码:

override func viewDidLoad() {
    super.viewDidLoad()

    let path = UIBezierPath()

    let p1 = CGPointMake(100, 100)
    let p2 = CGPointMake(300, 100)

    let c1 = CGPointMake(150, 80)
    let c2 = CGPointMake(250, 80)

    var midPoint = midPointForPoints(p1, p2: p2)

    var midP1 = midPoint
    midP1.x -= 10

    var midP2 = midPoint
    midP2.x += 10

    midPoint.y -= 20

    path.moveToPoint(p1)
    path.addQuadCurveToPoint(midP1, controlPoint: c1)
    path.addLineToPoint(midPoint)
    path.addLineToPoint(midP2)
    path.addQuadCurveToPoint(p2, controlPoint: c2)

    let shape = CAShapeLayer()
    shape.lineWidth = 5
    shape.strokeColor = UIColor.redColor().CGColor
    shape.fillColor = UIColor.clearColor().CGColor
    shape.path = path.CGPath

    self.view.layer.addSublayer(shape)

}


func midPointForPoints(p1: CGPoint, p2: CGPoint)->CGPoint{
    let deltaX = (p1.x + p2.x)/2
    let deltaY = (p1.y + p2.y)/2

    let midPoint = CGPointMake(deltaX, deltaY)

    return midPoint
}

这并没有考虑点的度数,因此如果我将两个点创建为:

This doesen't take the degrees of the points into account, so if I were to create the two points as:

let p1 = CGPointMake(100, 100)
let p2 = CGPointMake(300, 300)

找不到合适的控制点和中点.

It would not find the proper control points and midpoint.

希望有人可以在正确的方向帮助我.当然,最终的想法是只知道两个点(p1,p2)并动态创建所有其他点,而我只是暂时输入值,以便于自己使用.我添加了该问题的图像以更好地向您展示.

Hope someone can help me in the right direction. The idea is of course in the end to just know the two points (p1, p2) and dynamically create every other points, I just typed in values for the moment, to make it easier for myself. I've added images of the issue to better show you.

推荐答案

问题的关键是当图形旋转时,您的base vectors将旋转.当figure轴对齐时,您的基本向量是u (1, 0)v (0, 1).

The key to the problem is when the figure is rotated your base vectors will rotate. When your figure is axis-aligned your base vectors are u (1, 0) and v (0, 1).

因此,当您执行midPoint.y -= 20时,可以看到与midPoint.x -= v.x * 20; midPoint.y -= v.y * 20相同的内容,其中v(0, 1).结果是相同的,请检查一下自己.

So when you are performing midPoint.y -= 20 you can see it as the same as midPoint.x -= v.x * 20; midPoint.y -= v.y * 20 where v is (0, 1). The results are the same, check for yourself.

此实现将执行您的代码所执行的操作,仅axis independent.

This implementation will do what your code does, only axis independent.

let path = UIBezierPath()

let p1 = CGPointMake(100, 100)  
let p2 = CGPointMake(300, 100)  

let o = p1.plus(p2).divide(2.0) // origo
let u = p2.minus(o)             // base vector 1
let v = u.turn90()              // base vector 2

let c1 = o.minus(u.times(0.5)).minus(v.times(0.2))  // CGPointMake(150, 80)
let c2 = o.plus(u.times(0.5)).minus(v.times(0.2))   // CGPointMake(250, 80)

var midPoint = o.minus(v.times(0.2))

var midP1 = o.minus(u.times(0.2))
var midP2 = o.plus(u.times(0.2))

注意:我将因子设置为与您的实现中的初始值相匹配.

Note: I set the factors to match the initial values in your implementation.

为方便起见,还添加了此CGPoint extension.希望对您有所帮助.

Also added this CGPoint extension for convenience. Hope it helps.

extension CGPoint {
    public func plus(p: CGPoint) -> (CGPoint)
    {
        return CGPoint(x: self.x + p.x, y: self.y + p.y)
    }
    public func minus(p: CGPoint) -> (CGPoint)
    {
        return CGPoint(x: self.x - p.x, y: self.y - p.y)
    }
    public func times(f: CGFloat) -> (CGPoint)
    {
        return CGPoint(x: self.x * f, y: self.y * f)
    }
    public func divide(f: CGFloat) -> (CGPoint)
    {
        return self.times(1.0/f)
    }
    public func turn90() -> (CGPoint)
    {
        return CGPoint(x: -self.y, y: x)
    }
}

这篇关于从两点创建大括号曲线的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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