> On 14. Jan 2018, at 21:12, Kelvin Ma via swift-evolution > <swift-evolution@swift.org> wrote: > > This could work, but you’re also giving up all the nice Numeric and > FloatingPoint conformances when you use this,, all of a sudden adding two > angles together isn’t let γ = α + β, it’s γ = Angle.radians(α.radians + > β.radians). just no. at the risk of blowing up the scope of this idea, > dedicated Angle types also begs for generic trigonometric functions like > Angle.sin(_:) and Angle.cos(_:). i proposed that a while back and even tried > implementing it but fast trig evaluation doesn’t genericize well since it > relies a lot on rsqrt-style magic constants
You could add those conformances back, if you wanted. Most low-level trig code will quickly escape the wrapper once it starts using the values. Mostly I use it as a currency type and for converting untyped angles. I think it’s a great example of Swift’s zero-cost abstractions - we added semantic meaning (this value isn’t just a number with a specific bit representation, it’s a number which represents a specific kind of quantity), and encapsulated some useful functionality, and we don't lose any performance. I have a couple of these, such as Distance<T> and Time (wraps a TimeInterval). This allows me to write algorithms like: public func point(_ distance: Distance<Double>, along bearing: Angle<Double>) -> Geo.Point And use it like this: let nextPlace = thisPlace.point(.kilometers(42), along: .degrees(45)) Or this: let nextPlace = thisPlace.point(.miles(500), along: .radians(.pi/2)) And so my algorithm actually becomes quite difficult to use incorrectly. Also, that’s why I use static constructors; similar to how lots of OptionSet types are implemented, doing it this way lets you use an enum-like syntax to create values, which fits Angle’s intended use as a parameter/return type. I’m not saying this should be part of the standard library (this isn’t my pitch), I’m just saying these kind of wrappers are useful when creating good APIs. I think somebody was dismissing the idea of an Angle<T> type in general before. - Karl > > also, why are radians(_:) and degrees(_:) static functions? i really only use > static constructors for initializers that have side effects > > On Sun, Jan 14, 2018 at 6:36 AM, Karl Wagner <razie...@gmail.com > <mailto:razie...@gmail.com>> wrote: > > >> On 14. Jan 2018, at 09:51, Taylor Swift via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >> I do a lot of geometry and spherical-related work and i have never found an >> Angle type to be worth having. Always use radians. It’s what sin() and cos() >> take, it’s what graphics APIs like Cairo expect, it’s what graphics formats >> like SVG use. plus,, do you *really* want to be case-branching on every >> angle value? that really adds up when you’re converting 100,000s of lat-long >> pairs to cartesian. > > You can do it without case-branching. I too have an Angle type; this is what > I use: > > public struct Angle<T: FloatingPoint> { > public var radians: T > public var degrees: T { > return (radians / .pi) * 180 > } > > public static func radians(_ rads: T) -> Angle { > return Angle(radians: rads) > } > public static func degrees(_ degs: T) -> Angle { > return Angle(radians: (degs / 180) * .pi) > } > } > > If you ask for “radians” (like most low-level trig code will), you just get > the stored property. The conversion “overhead” is only done at construction > time, so it makes a convenient parameter/return value. > > - Karl > >> >> On Jan 14, 2018, at 12:04 AM, BJ Homer via swift-evolution >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >> >>> An Angle type already exists in Foundation; see Measurement<UnitAngle>. You >>> could add some convenience methods in an extension pretty easily. >>> >>> import Foundation >>> >>> typealias Angle = Measurement<UnitAngle> >>> >>> extension Measurement where UnitType == UnitAngle { >>> var sine: Double { >>> let radians = self.converted(to: .radians).value >>> return sin(radians) >>> } >>> >>> static var threeQuarterTurn: Angle { >>> return Angle(value: 0.75, unit: .revolutions) >>> } >>> } >>> >>> let x = Angle.threeQuarterTurn >>> x.sine // -1 >>> >>> -BJ >>> >>> >>>> On Jan 13, 2018, at 9:31 PM, Erica Sadun via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>> >>>> I would like to see a full Geometry implementation but I don't think it >>>> should be part of the standard library. >>>> >>>> I've kicked around some ideas here: >>>> >>>> * https://gist.github.com/erica/8cb4b21cf0c429828fad1d8ad459b71b >>>> <https://gist.github.com/erica/8cb4b21cf0c429828fad1d8ad459b71b> >>>> * https://gist.github.com/erica/ee06008202c9fed699bfa6254c42c721 >>>> <https://gist.github.com/erica/ee06008202c9fed699bfa6254c42c721> >>>> >>>> and >>>> >>>> * https://github.com/erica/SwiftGeometry >>>> <https://github.com/erica/SwiftGeometry> >>>> >>>>> On Jan 13, 2018, at 7:49 PM, Jonathan Hull via swift-evolution >>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>> >>>>> Hi Evolution, >>>>> >>>>> I would really like to see Swift gain an Angle type in the standard >>>>> library. Every time I have to deal with an angle in an api, I have to go >>>>> figure out the conventions for that call. Is it in degrees? Is it in >>>>> radians? What if it is in radians, but I want to think about it in >>>>> degrees? >>>>> >>>>> I ended up writing an Angle type for my own code a few years back, and I >>>>> have to say it is really wonderful. It has greatly simplified my >>>>> graphics work. It takes a lot of mental load off of my brain when >>>>> dealing with Angles. >>>>> >>>>> I can of course initialize it either as degrees or radians (or >>>>> revolutions), but I can also just say things like ‘.threeQuarterTurn’, >>>>> and then I can get the value back out in whatever format I like. There >>>>> are also useful additions that let me normalize the angle to different >>>>> ranges and which let me snap to the nearest multiple of an angle. Both of >>>>> these are enormously useful for user facing features. I can also do math >>>>> on angles in a way that makes geometric sense for angles. It is also >>>>> really useful for interacting with CGVectors in intelligent ways. >>>>> >>>>> Using Doubles or CGFloats to represent angles everywhere is just >>>>> semantically wrong IMHO, and it stops us from adding all of these >>>>> angle-specific niceties. >>>>> >>>>> Happy to provide code if there is interest… >>>>> >>>>> Thanks, >>>>> Jon >>>>> _______________________________________________ >>>>> swift-evolution mailing list >>>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>>> >>>> _______________________________________________ >>>> swift-evolution mailing list >>>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>>> https://lists.swift.org/mailman/listinfo/swift-evolution >>>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >>> >>> _______________________________________________ >>> swift-evolution mailing list >>> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >>> https://lists.swift.org/mailman/listinfo/swift-evolution >>> <https://lists.swift.org/mailman/listinfo/swift-evolution> >> _______________________________________________ >> swift-evolution mailing list >> swift-evolution@swift.org <mailto:swift-evolution@swift.org> >> https://lists.swift.org/mailman/listinfo/swift-evolution >> <https://lists.swift.org/mailman/listinfo/swift-evolution> > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution