Advertisement
Naeddyr

Equirectangular rotation, G'mic / GIMP / Krita

Aug 23rd, 2020
597
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.53 KB | None | 0 0
  1. # G'mic script to be used with the G'mic plugin in GIMP or Krita.
  2. # Paste this into a text-file. ".gmic" in your home directory on *nix or "user.gmic"
  3. # in /Users/%username%/AppData/Roaming (maybe) on Windows 10 at least.
  4.  
  5.  
  6.  
  7. #@gui ____<b>Map Projection</b>
  8. #-----------------------------
  9. #@gmic rotate_equirectangular_map : roll angle, pitch angle, yaw angle
  10. #@gmic : Take a map or equirectangular panorama
  11. #@gmic : and rotate it around three axises
  12.  
  13. #@gui Rotate Equirectangular Map : rotate_equirectangular_map
  14. #@gui : note = note("Rotate an equirectangular map or panorama around three axises in order in degrees.")
  15. #@gui : Roll = float(0,-360,360)
  16. #@gui : Pitch ("north and south" = float(0,-360,360)
  17. #@gui : Yaw ("east and west") = float(0,-360,360)
  18. #@gui : note = note("<small>Author: <i>Kristian Järventaus</i>.      Latest Update: <i>2020-08-23</i>.</small>")
  19.  
  20.  
  21. rotate_equirectangular_map :
  22.  
  23. # Default to 0 degrees
  24. -skip ${1=0},${2=0},${3=0}
  25.  
  26. # Black magic spell to make the preview look better???
  27. _fF_zoomaccurate=1
  28. _fF_zoomfactor=1
  29.  
  30.  
  31. # Create new image, the ""-block is the mathematical 'function' that
  32. # determines the value of the output pixel wherever we are iterating
  33.  
  34. 100%,100%,1,100%,"
  35.  
  36. # Command parameters from the command line or the sliders.
  37. # Variables from outside the ""-block have to be outside the ""s.
  38. yaw="{$3}";
  39. pitch="{$2}";
  40. roll="{$1}";
  41.  
  42. # Converting degrees into radians for the matrices later
  43. # Those minus signs are just a direction correction.
  44. alpha=-roll * pi / 180;
  45. beta=-pitch * pi / 180;
  46. gamma=-yaw * pi / 180;
  47.  
  48. # Equirectangular coordinates into spherical radians coordinates
  49. # phi <- height
  50. # theta <- width
  51. # radius rho=1, we are always working with a unit sphere / globe with radius 1
  52. # The extra pi in "otheta=PI..." is to offset the axis towards the center of the image
  53. otheta=pi + (x/w)*2*pi;
  54. ophi=(y/h)*pi;
  55. rho=1;
  56.  
  57. # Convert to Cartesian x, y, z, we can leave out rho=1
  58. # cx=rho*sin(ophi)*cos(otheta);
  59. # cy=rho*sin(ophi)*sin(otheta);
  60. # cz=rho*cos(ophi);
  61.  
  62. cx=sin(ophi)*cos(otheta);
  63. cy=sin(ophi)*sin(otheta);
  64. cz=cos(ophi);
  65.  
  66. # Do the transformation in Cartesian using rotation matrix maths magic
  67.  
  68. rotz=cz*( cos(alpha)*cos(beta) )
  69. + cy*( cos(alpha)*sin(beta)*sin(gamma) - sin(alpha)*cos(gamma) )
  70. + cx*( cos(alpha)*sin(beta)*cos(gamma) + sin(alpha)*sin(gamma) );
  71.  
  72. roty=cz*( sin(alpha)*cos(beta) )
  73. + cy*( sin(alpha)*sin(beta)*sin(gamma) + cos(alpha)*cos(gamma) )
  74. + cx*( sin(alpha)*sin(beta)*cos(gamma) - cos(alpha)*sin(gamma) );
  75.  
  76. rotx=cz*(-sin(beta))
  77. + cy*(cos(beta)*sin(gamma))
  78. + cx*(cos(beta)*cos(gamma));
  79.  
  80. # Convert the rotated point BACK into spherical coordinates
  81. # Atan2 is a special programming thing to do arctan, except better
  82. # It's got its own Wikipedia page
  83.  
  84. ntheta=atan2(roty, rotx);
  85. nphi=acos( rotz / sqrt(rotx*rotx + roty*roty + rotz*rotz) );
  86.  
  87. # Convert spherical coordinates almost straight back into
  88. # equirectangular pixel coordinates.
  89.  
  90. x2=( (ntheta/pi/2)*w+w/2 );
  91. y2=(nphi/pi)*h;
  92.  
  93. # I: from image #0 take the vector(pixel value) of x2,y2,z(=0)
  94. # "2": Cubic interpolation of pixels
  95. # "0": Boundary condition: if you hit "nothing", what do you do? N/A here.
  96.  
  97. I(#0,x2,y2,0,2,0)"
  98.  
  99. # Keep the last image generated ("k." = keep[-1] image index)
  100.  
  101. keep[-1]
  102.  
  103.  
  104.  
  105. #@gmic sinusoidal_map : yaw angle, pitch angle, roll angle, bgred, bggreen, bgblue, slices
  106. #@gmic : Take a map or equirectangular panorama
  107. #@gmic : and rotate it around z, y and x angles,
  108. #@gmic : then project it as a sliced sinusoidal map
  109.  
  110. #@gui Sinusoidal Map : sinusoidal_map
  111. #@gui : note = note("Rotate an equirectangular map or panorama around three axises in order and output it as a sinusoidal projection.")
  112. #@gui : Roll = float(0,-360,360)
  113. #@gui : Pitch ("north and south" = float(0,-360,360)
  114. #@gui : Yaw ("east and west") = float(0,-360,360)
  115. #@gui : Background color = color(128,128,128)
  116. #@gui : Slices = int(1,1,72)
  117. #@gui : note = note("<small>Author: <i>Kristian Järventaus</i>.      Latest Update: <i>2020-08-23</i>.</small>")
  118.  
  119.  
  120. sinusoidal_map :
  121.  
  122. # $1-3 Default to 0 degrees
  123. # $4-6 color(r,g,b) gives you three separate parameters instead of, say, a vector
  124. -skip ${1=0},${2=0},${3=0},${4=0},${5=0},${6=0} -check ${7=1}>=1
  125.  
  126. slices=$7
  127.  
  128. _fF_zoomaccurate=1
  129. _fF_zoomfactor=1
  130.  
  131. # First rotate the map with the appropriate custom command
  132. rotate_equirectangular_map $1,$2,$3
  133.  
  134. # Slice the rotated map image into vertical sections
  135. split x,$slices
  136.  
  137. # Loop over each slice. $! = number of images in the image list
  138. repeat $!
  139.  
  140. # No keyword: create an image. The ""-block is the mathematical function
  141. # whose result/return value at the end determines the value of the pixel
  142. # x, y we are iterating over.
  143. 100%,100%,1,100%,"
  144.  
  145. # Background color
  146. bgr="{$4}";
  147. bgg="{$5}";
  148. bgb="{$6}";
  149.  
  150. # Half-accidental magical formula. Half-sin is used to center the coordinates somehow??
  151. halfsin=sin( (y/h)*pi )*w / 2;
  152. x2=(x+halfsin-w/2)/sin( y/h*pi);
  153. # y = y in this case, just use original y.
  154.  
  155. # Check whether we're coloring inside or outside the sinusoidal shape
  156. if ( (x >= (w/2-halfsin) && x <= (w/2+halfsin) ),
  157. I(#"$>",x2,y,0,2,0),
  158. color=[bgr, bgg, bgb]);"
  159. # repeat-loop end
  160. done
  161.  
  162. # Delete the old map, which was sliced up
  163. remove[0-{$slices-1}]
  164.  
  165. # join all the rest (new) slices together in order on the x axis
  166. append x
  167.  
  168. # Keep the last (. = [-1] image index) image generated
  169. keep[-1]
  170.  
  171.  
  172.  
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement