Почему CGFloat, отлитый из Float, не демонстрирует поведение CGFloat? - PullRequest
0 голосов
/ 02 марта 2019

У меня есть простой пример, где я пытаюсь нарисовать круг.Этот код ниже не дает мне круг.

import UIKit

class PlayingCardView: UIView {

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext(){

            context.addArc(center: CGPoint(x: bounds.midX, 
                           y: bounds.midY), radius: 100.0, 
                           startAngle: 0, 
                           endAngle: CGFloat(2.0*Float.pi), 
                           clockwise: true)

            context.setLineWidth(5.0)
            UIColor.red.setStroke()
            context.strokePath()
            print(2.0*CGFloat.pi)
            print(CGFloat(2.0*Float.pi))
        } 
    }
}

Это - это то, что я получаю с кодом выше:

с выводом:

6.283185307179586 6.283185005187988

из операторов печати, которые соответствуют 2.0*CGFloat.pi и CGFloat(2.0*Float.pi) соответственно.

Обновление кода до этого (я изменяю только endAngle в context.addArc на 2.0*CGFloat.pi вместо CGFloat(2.0*Float.pi)

import UIKit

class PlayingCardView: UIView {

    override func draw(_ rect: CGRect) {
        if let context = UIGraphicsGetCurrentContext(){

            context.addArc(center: CGPoint(x: bounds.midX, 
                           y: bounds.midY), radius: 100.0, 
                           startAngle: 0, 
                           endAngle: 2.0*CGFloat.pi, 
                           clockwise: true)

            context.setLineWidth(5.0)
            UIColor.red.setStroke()
            context.strokePath()
            print(2.0*CGFloat.pi)
            print(CGFloat(2.0*Float.pi))
        } 
    }
}

Я получаю рисунок (круг есть)

Очевидно, что разница между CGFloat от Float и CGFloat есть.Кто-нибудь знает, что это такое и почему это поведение полезно в Swift?

1 Ответ

0 голосов
/ 02 марта 2019

На 64-битной платформе CGFloat - это (по существу) Double, 64-битное число с плавающей запятой, тогда как Float - 32-битное число с плавающей запятой.

Итак 2.0*Float.pi равно «2π с 32-битной точностью», и преобразование его в 64-битную величину CGFloat сохраняет значение без увеличения точности.

Именно поэтому 2.0*CGFloat.pi != CGFloat(2.0*Float.pi).Первый - «2π с 64-битной точностью», и это то, что вы должны передать функциям рисования.

В вашем конкретном случае CGFloat(2.0*Float.pi) чуть меньше 2.0*CGFloat.pi, так что толькорисуется невидимая короткая дуга (от радианов 0,0 до приблизительно -0,00000003).

Для полного круга вы также можете использовать

let radius: CGFloat = 100.0
context.addEllipse(in: CGRect(x: bounds.midX - radius, y: bounds.midY - radius,
                              width: 2.0 * radius, height: 2.0 * radius))

и избежать всех проблем с округлением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...