YOUR ACCOUNT

Login or Register to post new topics or replies
David Roberson
Artist
Posts: 404
Filters: 36
I'll begin this post by saying I've spent half the day studying this problem, and trying to wrap my brain around the trigonometry and matrix calculations of affine transforms, and needed to take a break. Anyone who's visited the forums recently knows I've been working on spherical noise generators, and I started the day updating them. Before updating the Library, I paused to ask if there was anything I was leaving out. For the Perlin noise version, I did not have an Angle control, and I knew that there was an Angle input I could add to the component. The problem was, how do I make use of one, if I add it?

So, lots of research and reading commenced. I did poke around to see if I had a filter with a map script in it that used some form of rotation, but there really isn't an efficient way to do that kind of search. So, that left asking the forum if anyone knew of or could provide a script for reference. Of course, there's no telling how long it might take to get a positive response, but you know what happens if you never even ask. It will take me a while to work through this on my own, so I decided to put the request out there in the meantime.

As always, any help is appreciated.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
On further consideration, I realize this might be a moot point, as far as my real objective is concerned. I'd gotten used to the quirks of taking 2D noise and compositing a spheremap, where playing with the Angle could produce interesting and useful variations. But, what I'm working with now is 3D noise. So, in that context, I'd really be trying to come up with rotation on x, y and z axes. That's probably too much to ask anyone to provide, however useful it'd be to me. If someone is up to the challenge, I'd love to see the example they'd come up with, but I'm not going to hold my breath.

I'd still like to know how to do 2D rotation, but it's more of an academic interest now that I've looked into it a bit.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
While I'm still logged in, I might as well share the script for a little oddity I came up with. I found a tiny function to rotate a vector and dropped it into a map script to see what it'd do. I found the output perplexing!

The code is simple, just create a map script with an Angle input, and paste this in:

Code
function prepare()
   angle = get_angle_input(ANGLE)
end;

function get_sample(x, y)
--   local r, g, b, a = get_sample_map(x, y, SOURCE)
--   local x, y = rotate(x,y,angle)
   local nx, ny = rotate(x,y,angle)
   local r = nx
   local g = ny
   local b = (nx + ny) / 2
   local a = 1
   return r, g, b, a
end;

function rotate(x, y, a)
  local c = math.cos(a)
  local s = math.sin(a)
  return c*x - s*y, s*x + c*y
end
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
This is not the first time I've tried to use an angle control in a map script, only to get a mysterious "unexpected nil value" errors or the like. I thought this time was simple enough, an angle offset script. The error comes when I return v on the following:

Code
function prepare()
   -- prepare
   dis = 5 -- get_slider_input(DISTANCE)
   dir = math.rad(get_angle_input(DIRECTION))
end;

function get_sample(x, y)
   nx = math.cos(dir)
   ny = math.cos(dir)
   -- get source
   v = get_sample_grayscale(x,y,SOURCE)
   x = x + nx * dis
   y = y + ny * dis
   return v
end;


Anyone care to help?
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
And its Any Angle Offset v2.0 By uberzev to the rescue! I knew it was out there, but couldn't find it on my computer. Working on the map script helped me think of the right search string to locate it in the Library. Even so, I'm going to want to know what I'm doing wrong with my map script, so help would still be appreciated!
  Details E-Mail
emme
Posts: 718
Filters: 8
The errors are because FF expects all the RGB values returned - you're only returning a single value. Using return v,v,v should fix the errors.

You also want to calculate the new coordinates before you sample the source image. Move the get_sample_grayscale below the new x/y coordinates.

I think there's a typo: nx = math.cos(dir) should use math.sin() instead.

Anyways, I don't think the script will rotate the image. Only offset it in a circular path.

Here is a script that rotates an image around a point:
Code

function prepare()
   ox,oy = get_slider_input(ORIGIN_X),get_slider_input(ORIGIN_Y)
   d = math.rad(get_angle_input(ROTATION))
   s,c = math.sin(d), math.cos(d)
end;

function get_sample(x, y)
   local nx = c * (x-ox) - s * (y-oy) + ox
   local ny = s * (x-ox) + c * (y-oy) + oy
   local r,g,b,a = get_sample_map(nx, ny, SOURCE)
   return r,g,b,a
end;
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
As always, emme, thank you for your sage advice! I will try your corrections out and tell you how it goes. I was originally interested in rotating an image, or coordinate samples inside perlin noise, but for this last experiment I was going for the circular offset. That's something I was able to do with uberzev's snippet, but it's nice to see how to script it. I really appreciate the rotation script. That will be a lot of help with figuring things out with my other ambitions.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
Okay, returning v,v,v did fix the error. I made the other corrections you suggested, but the resulting script behaves oddly, jumping around seemingly at random as I increase the angle. Here are the changes I made:

Code
function prepare()
   -- prepare
   dis = 0.5 -- get_slider_input(DISTANCE)
   dir = math.rad(get_angle_input(DIRECTION))
end;

function get_sample(x, y)
   nx = math.sin(dir)
   ny = math.cos(dir)
   -- get source
   x = x + nx * dis
   y = y + ny * dis
   v = get_sample_grayscale(x,y,SOURCE)
   return v,v,v
end;
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
On later thought, I wonder if part of the problem is that my circle offset script does not address X and Y Origins. I got up from a nap to pose that question, and I'll see if I can figure out how to test the theory myself next time I'm free to work on it. Thanks.
  Details E-Mail
James
James
Posts: 676
Filters: 46
Did anyone ever figure out how to rotate an input around a central point like the rotate node?

I have seen the following GLSL code:

Code
float s = sin(angle);
float c = cos(angle);

return mat2(
   c, -s,
   s, c
);


It is similar to the function David posted in the 3rd post which didn't seem to do anything for me. I am not sure how to recreate the mat2 matrix part of the GLSL however so I haven't got anything I have tried working yet.

I tried the code above but that seems to move the image around a radius rather than actually rotating it.
  Details E-Mail
emme
Posts: 718
Filters: 8
Quote
James wrote:
Did anyone ever figure out how to rotate an input around a central point like the rotate node?


Check few posts above smile;)
Quote
emme wrote:
Here is a script that rotates an image around a point:
Code

function prepare()
   ox,oy = get_slider_input(ORIGIN_X),get_slider_input(ORIGIN_Y)
   d = math.rad(get_angle_input(ROTATION))
   s,c = math.sin(d), math.cos(d)
end;

function get_sample(x, y)
   local nx = c * (x-ox) - s * (y-oy) + ox
   local ny = s * (x-ox) + c * (y-oy) + oy
   local r,g,b,a = get_sample_map(nx, ny, SOURCE)
   return r,g,b,a
end;

  Details E-Mail
James
James
Posts: 676
Filters: 46
That works great thanks smile:)

I noticed when increasing the angle it travels in the opposite direction to the default rotate node, so I just put the angle in a lerp function making it decrease in value as then it matches the behaviour of the default rotate node.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
@James

I revisited this thread to pick up emme's rotate script when I noticed your response, and I got curious about the lerp function you added. Could you explain how you used it? Given the same problem, I would have tried another method to invert the angle input. I'd be happy with just the code for the script, too. Thanks!
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
I have spent the past few days working on adding better rotation controls to map scripts derived fr om Planet Maker 3D by andyz. Along the way I visited Rotating 3D shapes wh ere I was able to fill in the blanks in my understanding of 3D rotations. I applied that to the script used in my current project, but I'm also interested in using the functions from that page to emulate the Angle control of Perlin Noise in a 3D Perlin Noise map script.

I made an attempt to convert the JS to Lua, but I think I need a more experienced set of eyes to tell if I'm on the right track. At the moment, I only have a vague idea how I'd use the functions in question.

Take a look:
Code

-- rotation functions js to lua
function prepare()
   -- input
   local theta = math.rad(get_angle_input(THETA))
   -- precalc, global vars for rotation functions
   sin_theta = sin(theta);
   cos_theta = cos(theta);
end;


function get_sample(x, y)
   -- incomplete, pass array as var?
   x, y, z = rotate_z3d(x,y,sin_theta,cos_theta), rotate_x3d(x,y,sin_theta,cos_theta), rotate_y3d(x,y,sin_theta,cos_theta)
end;


function rotate_z3d(x,y,sin_theta,cos_theta)
   for node_index = 0, NODE_COUNT  do
   local NODE = {}
   local NODE_COUNT
   local node_index
      if (node_index < nodes_length) then
         NODE_COUNT = node_index - 1
         break
      NODE[node_index] = {x,y}
      y = y * cos_theta - z * sin_theta
      z = z * cos_theta + y * sin_theta
   end
  
  
end;
function rotate_x3d(x,y,sin_theta,cos_theta)
   local NODE = {}
   local NODE_COUNT
   local node_index
  for node_index = 0, NODE_COUNT  do
      if (node_index < nodes_length) then
         NODE_COUNT = node_index - 1
         break
      NODE[node_index] = {x,y}
      y = y * cos_theta - z * sin_theta
      z = z * cos_theta + y * sin_theta
   end
  
  
end;
= function rotate_y3d(x,y,sin_theta,cos_theta)
   local NODE = {}
   local NODE_COUNT
   local node_index
  for node_index = 0, NODE_COUNT  do
      if (node_index < nodes_length) then
         NODE_COUNT = node_index - 1
         break
      NODE[node_index] = {x,y}
      y = y * cos_theta - z * sin_theta
      z = z * cos_theta + y * sin_theta
   end
end;


Here is the JS:

Code
// rotation functions from js

   var rotateZ3D = function(theta) {
      var sinTheta = sin(theta);
      var cosTheta = cos(theta);
      for (var n = 0; n < nodes.length; n++) {
        var node = nodes[n];
        var x = node[0];
        var y = node[1];
        node[0] = x * cosTheta - y * sinTheta;
        node[1] = y * cosTheta + x * sinTheta;
      }
   };
   var rotateX3D = function(theta) {
      var sinTheta = sin(theta);
      var cosTheta = cos(theta);
      for (var n = 0; n < nodes.length; n++) {
        var node = nodes[n];
        var y = node[1];
        var z = node[2];
        node[1] = y * cosTheta - z * sinTheta;
        node[2] = z * cosTheta + y * sinTheta;
      }
   };
   var rotateY3D = function(theta) {
      var sinTheta = sin(theta);
      var cosTheta = cos(theta);
      for (var n = 0; n < nodes.length; n++) {
        var node = nodes[n];
        var x = node[0];
        var z = node[2];
        node[0] = x * cosTheta + z * sinTheta;
        node[2] = z * cosTheta - x * sinTheta;
      }
   };
  Details E-Mail
SpaceRay
SpaceRay

Posts: 12298
Filters: 35
Sorry that I can not help you as I have no knowledge of scripting, but I really admire all of you that are able to do it and be able to go beyond what can be done with the FF components and make such creative things that are not possible in other ways
  Details E-Mail

Join Our Community!

Filter Forge has a thriving, vibrant, knowledgeable user community. Feel free to join us and have fun!

33,711 Registered Users
+18 new in 30 days!

153,533 Posts
+38 new in 30 days!

15,348 Topics
+73 new in year!

Create an Account

Online Users Last minute:

33 unregistered users.

Recent Forum Posts: