rotate an image
anna
I have two questions for whoever can help me... I have been searching in the forum and I think that there is no easy solution to my problem, but I will ask anyway. Here are my doubts:
- I have an image made up by a 2D crystal lattice points (see image attached). I would like to rotate the lattice, the points, about the origin at an angle that I decide, which can change. Is there an easy way to do it?
- I would like to 'mirror' the same image not about an axis, but about a line that passes through the origin at, say, 30º, and I would like to be able to change the angle of this mirroring line... Is this possible?
Thanks a lot in advance!
No doubt there'll be an inbuilt transform to do the same thing.
Wrt to the mirroring, that should be straightforward as well.
March 21, 2011 at 06:08 am - Permalink
http://en.wikipedia.org/wiki/Molecular_symmetry
.. and equivalent hard copy resources. Once you express your lattice as a [x, y] vector matrix, on hand the proper matrix operation, you can do any form of symmetry operation you want using the MatrixOp abilities in Igor Pro.
--
J. J. Weimer
Chemistry / Chemical & Materials Engineering, UAHuntsville
March 21, 2011 at 05:30 pm - Permalink
Try this. It performs "unitful" rotations (i.e., respecting the x and y scaling) about (0,0). If you want to rotate about a different point, just shift your origin. The output is returned as M_rotated2D. The optional useInterp parameter alters how "jagged" the output is. Try it both ways just to see what I mean.
By the way, the output is automatically resized to preserve the number of points along each edge. The space around your image will just be set to NaN.
Wave w // 2D image
Variable angle // degrees
Variable useInterp
if(ParamIsDefault(useInterp))
useInterp = 1 // default uses interpolation
endif
angle *= -pi/180 // convert to radians, negative sign for correct direction
Variable origX0 = DimOffset(w, 0)
Variable origX1 = DimOffset(w, 0)+DimDelta(w, 0)*(DimSize(w, 0)-1)
Variable origdX = DimDelta(w, 0)
Variable origY0 = DimOffset(w, 1)
Variable origY1 = DimOffset(w, 1)+DimDelta(w, 1)*(DimSize(w, 1)-1)
Variable origdY = DimDelta(w, 1)
// calculate new x's and y's of the corners
Variable xc1 = origX0*cos(angle)+origY0*sin(angle)
Variable yc1 = -origX0*sin(angle)+origY0*cos(angle)
Variable xc2 = origX0*cos(angle)+origY1*sin(angle)
Variable yc2 = -origX0*sin(angle)+origY1*cos(angle)
Variable xc3 = origX1*cos(angle)+origY0*sin(angle)
Variable yc3 = -origX1*sin(angle)+origY0*cos(angle)
Variable xc4 = origX1*cos(angle)+origY1*sin(angle)
Variable yc4 = -origX1*sin(angle)+origY1*cos(angle)
Variable x0 = min(min(xc1, xc2), min(xc3, xc4))
Variable x1 = max(max(xc1, xc2), max(xc3, xc4))
Variable y0 = min(min(yc1, yc2), min(yc3, yc4))
Variable y1 = max(max(yc1, yc2), max(yc3, yc4))
Variable rows = round( sqrt( ( DimSize(w, 0)*cos(angle) )^2 + ( DimSize(w, 1)*sin(angle) )^2 ) )
Variable cols = round( sqrt( ( DimSize(w, 0)*sin(angle) )^2 + ( DimSize(w, 1)*cos(angle) )^2 ) )
Make/D/O/N=(rows, cols) M_rotated2D
SetScale/I x, x0, x1, M_rotated2D
SetScale/I y, y0, y1, M_rotated2D
// fill the final image
if(useInterp)
MultiThread M_rotated2D = InRange(x*cos(-angle)+y*sin(-angle), origX0, origX1) && InRange(-x*sin(-angle)+y*cos(-angle), origY0, origY1) ? Interp2D(w, x*cos(-angle)+y*sin(-angle), -x*sin(-angle)+y*cos(-angle)) : NaN
else
MultiThread M_rotated2D = InRange(x*cos(-angle)+y*sin(-angle), origX0, origX1) && InRange(-x*sin(-angle)+y*cos(-angle), origY0, origY1) ? w(x*cos(-angle)+y*sin(-angle))(-x*sin(-angle)+y*cos(-angle)) : NaN
endif
End
ThreadSafe Static Function InRange(val, lim1, lim2)
Variable val, lim1, lim2
return (val >= lim1 && val < lim2) || (val < lim1 && val >= lim2)
End
Good luck,
Nick
March 22, 2011 at 10:23 am - Permalink