views:

1334

answers:

5

I'm writing a script where icons rotate around a given pivot (or origin). I've been able to make this work for rotating the icons around an ellipse but I also want to have them move around the perimeter of a rectangle of a certain width, height and origin.

I'm doing it this way because my current code stores all the coords in an array with each angle integer as the key, and reusing this code would be much easier to work with.

If someone could give me an example of a 100x150 rectangle, that would be great.

EDIT: to clarify, by rotating around I mean moving around the perimeter (or orbiting) of a shape.

A: 

If think you mean rotate like the earth rotates around the sun (not the self-rotation... so your question is about how to slide along the edges of a rectangle?)

If so, you can give this a try:

# pseudo coode
for i = 0 to 499
  if i < 100:  x++
  else if i < 250: y--
  else if i < 350: x--
  else y++

  drawTheIcon(x, y)

Update: (please see comment below)

to use an angle, one line will be

y / x = tan(th)       # th is the angle

the other lines are simple since they are just horizontal or vertical. so for example, it is x = 50 and you can put that into the line above to get the y. do that for the intersection of the horizontal line and vertical line (for example, angle is 60 degree and it shoot "NorthEast"... now you have two points. Then the point that is closest to the origin is the one that hits the rectangle first).

動靜能量
Thanks for the reply. This would work if I were actually working out the perimeter and working from there, but I'm actually storing the coordinates in an array of angles, so using the angle in an equation is a requirement.
Andy E
i think that will be solving the equation for those 2 lines, and find the x and y... and since it can hit two lines going one way, choose the one that has the smaller distance from origin.
動靜能量
+4  A: 
Magnus Skog
I'm having a little trouble understanding your answer despite it seeming like the actual solution I'm looking for. I understand splitting it into 4 triangles and d = √(w*w + h*h). Is it possible you could imagine you are working with a complete idiot at maths, and then rephrase your answer?
Andy E
the comment system doesn't appear to accept HTML entities. √ means square root (√).
Andy E
I'll get back to you once I get home and can use a reasonable program to draw you an image :) Cheers.
Magnus Skog
Well it certainly helped. I was initially confused by your use of d (which is normally defined as the diagonal of a rectangle) and atan (which is arctangent in javascript), but with some reading, re-reading and trial and error, I managed to get it working. I'm marking yours as the answer but I'll also answer with my own solution just in case anyone else comes here looking and is as confused as I was :)
Andy E
Sorry Magnus, I didn't realize that I couldn't mark two answers and I didn't notice that it unset your answer. Since it was wrong anyway, I deleted my own answer. I couldn't actually figure out from your post how to work out which side the ray intersects, "-atan(d/w) < alfa < atan(d/w)" doesn't make much sense to me :) Again, sorry that your post was unmarked as the answer.
Andy E
A: 

Hi

Draw yourself a sketch on a piece of paper with a rectangle and a centre of rotation. First translate the rectangle to centre at the origin of your coordinate system (remember the translation parameters, you'll need to reverse the translation later). Rotate the rectangle so that its sides are parallel to the coordinate axes (same reason).

Now you have a triangle with known angle at the origin, the opposite side is of known length (half of the length of one side of the rectangle), and you can now:

-- solve the triangle

-- undo the rotation

-- undo the translation

Regards

Mark

High Performance Mark
A: 

One simple way to do this using an angle as a parameter is to simply clip the X and Y values using the bounds of the rectangle. In other words, calculate position as though the icon will rotate around a circular or elliptical path, then apply this:

(Assuming axis-aligned rectangle centered at (0,0), with X-axis length of XAxis and Y-axis length of YAxis):

if (X > XAxis/2)    
         X = XAxis/2;

if (X < 0 - XAxis/2)
         X = 0 - XAxis/2;

if (Y > YAxis/2)    
         Y = YAxis/2;

if (Y < 0 - YAxis/2)    
         Y = 0 - YAxis/2;

The problem with this approach is that the angle will not be entirely accurate and the speed along the perimeter of the rectangle will not be constant. Modelling an ellipse that osculates the rectangle at its corners can minimize the effect, but if you are looking for a smooth, constant-speed "orbit," this method will not be adequate.

breitak67
The movement of the icons will be animated, so I do need it to be a smooth motion. Thanks anyway.
Andy E
A: 

Use a 2D transformation matrix. Many languages (e.g. Java) support this natively (look up AffineTransformation); otherwise, write out a routine to do rotation yourself, once, debug it well, and use it forever. I must have five of them written in different languages.

Once you can do the rotation simply, find the location on the rectangle by doing line-line intersection. Find the center of the orbited icon by intersecting two lines:

  1. A ray from your center of rotation at the angle you desire
  2. One of the four sides, bounded by what angle you want (the four quadrants).
Alex Feinman