我试着快速制作一个时钟,但现在我想做一些奇怪的事情。我想让边框半径可设置。这是容易的部分(很简单,因为我已经这样做了)。我全天抽了60个蜱虫。问题是60个刻度是一个完美的圆圈。如果我改变边界半径,我会得到这个时钟:
所有刻度都是使用NSBezierPath制作的,每个刻度的计算位置代码是:
let bezierPath = NSBezierPath(roundedRect:self.bounds, xRadius:currentRadius, yRadius:currentRadius)
point1和point2是12个时钟滴答的点。
我的时钟背景是用bezier路径制作的:
.parallax7 {
background-color: #FF783E;
background-image: url('../images/parallax-bg-7.jpg');
background-size: 100% auto;
}
currentRadius - 是一个可设置的var,所以我的背景是从一个完美的圆(当圆角半径=高度/ 2)到一个正方形(当圆角半径= 0时)。
是否有任何公式计算每个刻度的位置,因此,对于任何边界半径,最后所有刻度与边界的距离是否相同?
答案 0 :(得分:2)
如果不借助图形图解释数学是相当复杂的,但基本上如果你考虑在时钟中心使用原点的极坐标方法,那么有两种情况:
这个功能可以做到:
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