You're exactly right - if you construct a function like the following, I
think it will almost certainly result in four separate transformations
every time it's called:
compositeTransformation1 : Point3d -> Point3d
compositeTransformation1 =
Point3d.scaleAbout Point3d.origin 5 >> Point3d.rotateAround Axis3d.z
(degrees
90) >> Point3d.translateBy (Vector3d ( 1, 2, 3 )) >> Point3d.mirrorAcross
Plane3d.xy
In many cases that's fine (if you're only doing it for a handful of points,
for instance), but if you need a more efficient version you can do it using
frames:
transformedFrame : Frame3d
transformedFrame =
Frame3d.xyz |> Frame3d.rotateAround Axis3d.z (degrees 90) |>
Frame3d.translateBy
(Vector3d ( 1, 2, 3 ) |> Frame3d.mirrorAcross Plane3d.xy
compositeTransformation2 : Point3d -> Point3d
compositeTransformation2 =
Point3d.scaleAbout Point3d.origin 5 >> Point3d.placeIn transformedFrame
You still need to apply the scaleAbout separately since you can't scale a
Frame3d, but at least scaling is a relatively cheap operation.
In general, yes, using matrices would likely be a bit more efficient, but
you can get pretty close using techniques like the above, and I think the
expressiveness/clarity/flexibility is better. Precision should also be
improved - even disregarding the fact that the linear-algebra package uses
single-precision floats internally (via Float32Array), specialized
transformation functions like scaleAbout can do things like subtract the
given center point, then scale, then re-add the given center point. This
has better numerical stability than the equivalent transformation matrix,
which will effectively scale everything about the origin and then apply a
(potentially large) translation to drag everything back to where it should
be. (Several of these tradeoffs are probably affected by my own goals - I
want opensolid/geometry to be a great general-purpose geometry library, but
I'm personally more focused on stuff like computer-aided design apps where
precision is critical than things like games that have much more strict
performance requirements.)
By the way, the interop package I mentioned earlier has now been published:
http://package.elm-lang.org/packages/opensolid/linear-algebra/latest.
On Monday, 8 May 2017 05:22:05 UTC-4, Rupert Smith wrote:
>
> On Sunday, May 7, 2017 at 10:02:43 PM UTC+1, Rupert Smith wrote:
>>
>> On Friday, May 5, 2017 at 7:55:22 PM UTC+1, Ian Mackenzie wrote:
>>>
>>> So, nice library with lots of features, missed chance to work with a
>>>> better abstraction.
>>>>
>>>
>>> Ouch =) I've done lots of work with matrix-based libraries, and I've
>>> personally found matrices (and related stuff like quaternions) very
>>> powerful and flexible but also confusion- and error-prone. The OpenSolid
>>> libraries are my attempt to provide a better, more geometrically meaningful
>>> abstraction that still allows you to get good performance.
>>>
>>
>> Sorry, my bad and thanks for the explanation. I guess I was a little
>> fixated on the matrix approach, but with your explanation it is clear that
>> your approach is at least as good.
>>
>
> There is potentially an advantage with matrices versus functions. A matrix
> could be thought of as a function, in the sense that its values capture a
> particular function that can be applied by multiplying by it. So you have
> captured the function as a lambda. Lambdas are opaque though, and when
> chained together to produce a new function, there is no way to guarantee
> that they will combine in such a way that they reduce to the simplest or
> most efficient representation; the compiler may do a good job though.
>
> Suppose you have a complex chain of transformations like: scale, rotate,
> translate (requires 3x3 matrix for 2d work), mirror. Represent this with
> matrices M1, .., M4. The entire transformation can then be captured as a
> single matrix Mt = M1 . M2 . M3 . M4. As lambdas, my assumption is the
> compiler will not be smart enough to reduce it so neatly, and it will
> always be applied as 4 separate operations.
>
> I guess you already know this... :-)
>
--
You received this message because you are subscribed to the Google Groups "Elm
Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.