gpt4 book ai didi

xcode - 如何使时钟滴答声粘在时钟边框上?

转载 作者:搜寻专家 更新时间:2023-10-31 22:50:22 26 4
gpt4 key购买 nike

我试着快速制作一个时钟,但现在我想制作一些奇怪的东西。我想让边框半径可设置。这是容易的部分(很容易,因为我已经做到了)。我全天候画了 60 个刻度。问题是 60 个刻度是一个完美的圆。如果我改变边界半径我得到这个时钟:

enter image description here

所有报价都是用 NSBezierPath 制作的,计算每个报价的位置的代码是:

tickPath.moveToPoint(CGPoint(
x: center.x + cos(angle) * point1 ,
y: center.y + sin(angle) * point1
))

tickPath.lineToPoint(CGPoint(
x: center.x + cos(angle) * point2,
y: center.y + sin(angle) * point2
))

point1 和 point2 是 12 个时钟周期的点。

我的时钟背景是用贝塞尔曲线制作的:

 let bezierPath = NSBezierPath(roundedRect:self.bounds, xRadius:currentRadius, yRadius:currentRadius) 

currentRadius - 是一个可设置的 var ,所以我的背景是从完美的圆(当角半径 = 高度/2 时)到正方形(当角半径 = 0 时)。

是否有任何公式可以计算每个刻度的位置,因此对于任何边界半径,最终所有刻度与边界的距离相同?

最佳答案

如果不求助于图表,数学解释起来相当复杂,但基本上,如果您考虑原点在时钟中心的极坐标方法,那么有两种情况:

  • 从原点开始的辐条与正方形的直边相交的地方——三角学很容易
  • 它在拐角处碰到圆弧的地方——我们使用余弦法则求解由钟心、拐角圆心和辐条穿过拐角的点形成的三角形。该三角形的原点方向角度为 45º - angleOfSpoke,其中两条边的长度已知。将余弦方程求解为二次方程即可。

这个函数是这样做的:

func radiusAtAngle(angleOfSpoke: Double, radius: Double, cornerRadius: Double) -> Double {
// radius is the half-width of the square, = the full radius of the circle
// cornerRadius is, of course, the corner radius.
// angleOfSpoke is the (maths convention) angle of the spoke
// the function returns the radius of the spoke.

let theta = atan((radius - cornerRadius) / radius) // This determines which case

let modAngle = angleOfSpoke % M_PI_2 // By symmetry we need only consider the first quadrant

if modAngle <= theta { // it's on the vertical flat
return radius / cos(modAngle)
} else if modAngle > M_PI_2 - theta { // it's on the horizontal flat
return radius / cos(M_PI_2 - modAngle)
} else { // it's on the corner arc
// We are using the cosine rule to solve the triangle formed by
// the clock centre, the curved corner's centre,
// and the point of intersection of the spoke.
// Then use quadratic solution to solve for the radius.
let diagonal = hypot(radius - cornerRadius, radius - cornerRadius)
let rcosa = diagonal * cos(M_PI_4 - modAngle)
let sqrTerm = rcosa * rcosa - diagonal * diagonal + cornerRadius * cornerRadius
if sqrTerm < 0.0 {
println("Aaargh - Negative term") // Doesn't happen - use assert in production
return 0.0
} else {
return rcosa + sqrt(sqrTerm) // larger of the two solutions
}
}
}

在图中 OP = 对角线,OA = 半径,PS = PB = cornerRadius,OS = 函数返回,BÔX = theta,SÔX = angleOfSpoke

Diagram of solution

关于xcode - 如何使时钟滴答声粘在时钟边框上?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30131475/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com