Open ConnectedSystems opened 3 months ago
You can use any package like Rotations.jl in GeometryOps.transform
. transform
will give you an SVector for each point.
It will work on any geometry or arrays/feature collections/dataframes of geometries.
If using Rotations.jl you will need to wrap it in a CoordinateTransformations.LinearMap or so.
Can't get this to work though I feel as I am halfway there.
@asinghvi17 what do you mean by wrap "it" with a LinearMap
. Wrap what exactly? The RotMatrix
? Any further pointers would be appreciated.
GO.transform(transf, geom)
works by calling transf(point)
for each point in geom
. Rotations.jl doesn't subscribe to the CoordinateTransformations.jl way of doing things (which is just making the struct callable) and is also purely 3D, so you need to adjust it for 2D anyway.
Consider the following:
julia> import GeometryOps as GO; import Rotations, CoordinateTransformations
julia> points = tuple.(rand(10), randn(10));
julia> GO.transform(Rotations.RotX(π/4), points)
ERROR: MethodError: objects of type RotX{Float64} are not callable
Use square brackets [] for indexing an Array.
Stacktrace:
[...]
julia> rotation_matrix = Rotations.RotX(π/4)[1:2, 1:2] |> CoordinateTransformations.LinearMap
LinearMap([1.0 0.0; 0.0 0.7071067811865476])
julia> GO.transform(rotation_matrix, points)
[...]
rotation_matrix = Rotations.RotX(π/4)[1:2, 1:2] |> CoordinateTransformations.LinearMap
This was what I was missing!
I was playing around with the GO.transform(f, geom)
method instead.
Thanks! Now I can replace my crude rotation function.
Actually, this seems to only work for lines.
For other more complex geoms, it doesn't behave as I would expect.
using CoordinateTransformations, Rotations
using GLMakie, GeoMakie
pnts = [(1, 3), (3, 3), (3, 1), (1, 1), (1,3)];
rotation_matrix = RotX(0.0)[1:2, 1:2] |> LinearMap
poly(pnts, alpha=0.2)
for deg in [45.0, 90.0, 180.0]
rotation_matrix = RotX(deg2rad(deg))[1:2, 1:2] |> LinearMap
rot_geom = Tuple.(GO.transform(rotation_matrix, pnts))
poly!(rot_geom, alpha=0.3)
end
My bad, it should have been RotZ
.
using CoordinateTransformations, Rotations
using GLMakie, GeoMakie
import GeometryOps as GO
pnts = [(1, 3), (3, 3), (3, 1), (1, 1), (1,3)];
rotation_matrix = RotZ(0.0)[1:2, 1:2] |> LinearMap
poly(pnts, alpha=0.2)
for deg in [45.0, 90.0, 180.0]
rotation_matrix = RotZ(deg2rad(deg))[1:2, 1:2] |> LinearMap
rot_geom = Tuple.(GO.transform(rotation_matrix, pnts))
poly!(rot_geom, alpha=0.3)
end
You can also create your own matrix fairly easily:
using StaticArrays # so we don't allocate
rotmatrix2d(a #= angle =#) = StaticArrays.Mat2(cos(a), sin(a), -sin(a), cos(a))
poly(pnts, alpha=0.2)
for deg in [45.0, 90.0, 180.0]
rotation_matrix = rotmatrix2d(deg2rad(deg)) |> LinearMap
rot_geom = Tuple.(GO.transform(rotation_matrix, pnts))
poly!(rot_geom, alpha=0.3)
end
Before I get too stuck into writing my own methods, is there any way of rotating an arbitrary polygon by some degrees?
I'm hoping for something like
rotate(poly, 10.0)