I'm trying to make a bunch of rectangles that rotate around a given point, my code so far is this
function _update() timer+=0.01 velocity_x=cos(timer) velocity_y=sin(timer) for vect in all(rotographic) do vect+=velocity_x*radius vect+=velocity_y*radius vect+=velocity_x*radius vect+=velocity_y*radius end end function _draw() cls(0) for v in all(rotographic) do rectfill (v,v,v,v,flr(rnd(15)+1)) end end
"rotographic" is a table in which each cell contains a 4 value vector with the x and y positoins of origin and destnation to feed to rectfills. So far this works fine making the squares, however, all they do is rotate together, around their own center if I am not wrong.
What I want to achieve, is for the each rect to rotate around a given center (let's say 64,64 to exemplify) so in the given example, what would happen is, the outer rects will rotate around a bigger radius than the inner ones.
I know I'm failing at math here (no surprises) so I hope you guys can nudge me in the right direction!
I read this very helpful article, but I am failing to figure out how to apply its logic to more than one element in the data structure I have.
At first I thought this was going to be a question about how to define a rotated rectangle(versus an AABB one). Then I thought you were asking for something more like how to describe "parent" and "child" transformations like in the classic case of the double pendulum. But now I think I can describe it in two parts:
For the general case of "how to compose various transformations on geometry", matrix math is your friend. You can often avoid actually using a matrix and instead simplify to the parts that are relevant(here, the cos() and sin() functions plus some arithmetic will take care of everything). If you want to generalize a lot of rotations, translations, and scaling, though, a matrix library can help with that.
- For the specific case of representing various rectangles that all orbit a single point, the key thing you're missing is the concept of an offset value and being able to change where/when an offset is applied. What the orbiting of the rectangles represents is a kind of oscillator, like the LFO found on synthesizers. An LFO that is updated frame-by-frame and might vary in speed over time can be represented in code as an offset - what point the oscillation is currently at - and an increment - how much it progresses each tick. Each time you update, you might increment it by a different amount. Then the result of the oscillator's output is turned into x and y coordinates which are added to the center point.
This is a case of being able to represent the same visual info in different ways. Right now your code heavily weighs towards storing exactly the thing that is being drawn on screen, with the actual coordinates of each rectangle getting pushed around every frame. This makes it difficult to reason about where the rectangle is relative to a center point, which is why you are having trouble. What you are doing with "timer" and "velocity_x" and "velocity_y" is a kind of offset and increment, but the way you have it, it's both the oscillator's offset that gets changed over time, and the actual x and y points of the rectangles, as if they were a kind of physics system, propelled with an invisible force that happens to move in a circle over time.
This representation means that it's hard to figure out where the rectangles are in terms of an orbit, since that information is lost when it gets turned into x/y values and only an approximation can be regained, by applying atan2() - plus if you try to slow down or speed up the orbit by adjusting the velocity parameters, the rectangles will fall off-center since nothing is holding them in the right place. And, you might want this kind of behavior for some effects! It's just unclean if what you really want is something that always stays locked to a certain center position, and will do so even if the center jumps around or the velocity changes. To get this other behavior, define the data structure in terms of the center point and offset. Initialize the rectangles with different offset values, and update them by incrementing the offset. Then, in the draw function, compute everything else about the rectangle: the x/y relative to the center based on the offset, and the size relative to the x and y.
That took a couple of readings but I think I understood, thanks so much for that detailed post.
Yes, I realize that there needs to be some sort of offset, and I couldn't figure out where to put it. That is definitely my main problem and I will try to solve it by changing the data structure.
There's another problem, which is that I would like to be able to play with the numbers in a way that allows me to turn this back into a square grid of rectangles like it is displayed now. But I guess that is a problem for later.
[Please log in to post a comment]