Circular Layout

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • RedSon
    Recognized Expert Expert
    • Jan 2007
    • 4980

    Circular Layout

    Hi all,

    I have a problem where I have 1..n icons that I would like to layout in a circular pattern. Starting at an origin of (120, 160) I'm trying to figure out how to iterate over the collection of items and assign them a new position offset from the origin. Each of these items is a square of 48px and they cannot overlap.

    How in the world do I do it? I know I'll be needing to use my trig on this, but it's been so long I forgot most of it :(

    Thanks.
  • Dormilich
    Recognized Expert Expert
    • Aug 2008
    • 8694

    #2
    roughly speaking they need a distance of about 75px (48px · 2^0.5) from each other, the direction depends on the number n. so minimum radius of the circle should be n · 75px / 2 pi for n > 4 (to make it a sensible approximation).

    ..... if I've understood the problem right.

    edit>>>
    if you have a symmetry group of D[(2n)d] (i.e. an even number of pictures) you can reduce the calculation effort to one fourth (otherwise, one half)
    <<<
    Last edited by Dormilich; Jan 27 '09, 09:10 PM. Reason: added symmetry group info

    Comment

    • RedSon
      Recognized Expert Expert
      • Jan 2007
      • 4980

      #3
      Here is what I have now (link):

      Code:
      Vector2 origin = new Vector2(viewport.Width / 2, viewport.Height / 2);
      
      int radius = 48;
      double factor = ((2 * Math.PI) / menuEntries.Count);
      
      // Draw each menu entry in turn.
      foreach (MenuEntry entry in menuEntries.Values)
      {
          int i = menuEntries.IndexOfValue(entry);
          bool isSelected = IsActive && (i == selectedEntry);
      
          iconPos.X = (float)radius * (float)Math.Cos(factor * i + 1);
          iconPos.Y = (float)radius * (float)Math.Sin(factor * i + 1);
      
          entry.Draw(this, Vector2.Add(iconPos,origin), isSelected, gameTime);
      }
      Now there is no way I can tell if there are an even number of pictures or not, but I would be interested in optimizing the calculations.

      The radius will likewise need to be calculated but it is currently hard coded.

      Is this implementation close to what you were thinking?

      Comment

      • Dormilich
        Recognized Expert Expert
        • Aug 2008
        • 8694

        #4
        Originally posted by RedSon
        Is this implementation close to what you were thinking?
        yes, the only thing I wonder is why you use an initial rotation of 57° 17′ 44.8″.

        you should check if the radius given is large enough, so that the icons do not overlap.
        Code:
        r(min) = n · icon.width / ( sqroot(2) · pi )
        note that this approximation does not work for n < 5, thus a good default radius is necessary (48px should do)

        for drawing optimization compute the circle with the origin at (0, 0) and add position on screen later. (seems like you already did that)

        you can use a rotation matrix
        Code:
        cos(a)	–sin(a)
        sin(a)	 cos(a)
        so you only need to compute the first point and then repeatedly (n–1 times) apply the matrix in a iterative way.
        Code:
        x(0) = r · sin(a_ini)
        y(0) = r · cos(a_ini)
        // a_ini is the initial angle you want, 0 is vertical, top
        
        x(i+1) = x(i) · cos(a) – y(i) · sin(a);
        y(i+1) = x(i) · sin(a) + y(i) · sin(a)
        // where a = 2·pi / n
        note: I don't know how to code in C#

        Comment

        • JosAH
          Recognized Expert MVP
          • Mar 2007
          • 11453

          #5
          Are those icons shown in an upright position (i.e. no tilt)?

          kind regards,

          Jos

          Comment

          • RedSon
            Recognized Expert Expert
            • Jan 2007
            • 4980

            #6
            @Jos: The icons in my application are not rotated in any way when they are drawn on the screen.

            @Dormilich: Why do you say I use an initial rotation of 57° 17′ 44.8″?

            Also, I would use this formula
            Code:
            r(min) = n · icon.width / ( sqroot(2) · pi )
            but the screen size is so small having 5 or more icons creates a great amount of clutter. Is there a way to modify this such that r(min) can be calculated for n > 1?

            Comment

            • RedSon
              Recognized Expert Expert
              • Jan 2007
              • 4980

              #7
              Also would either of you be willing to do some code review on the project I linked to in post 3?

              You can use the web based svn viewer and double click on any line to make comments on that line. You don't have to know C# to be able to intuit what is going on with it.

              Comment

              • Dormilich
                Recognized Expert Expert
                • Aug 2008
                • 8694

                #8
                Originally posted by RedSon
                Why do you say I use an initial rotation of 57° 17′ 44.8″
                Code:
                Math.Cos(factor * i + 1)
                57° 17′ 44.8″ = 1 (rad),
                like usual in maths, if you add in y = f(x) a value to x, you shift the function by –x

                Originally posted by RedSon
                Is there a way to modify this such that r(min) can be calculated for n > 1?
                sure,
                n = 2: r(min) = 0.5 · icon.width;
                n = 3: r(min) = sqroot(2/3) · icon.width;
                n = 4: r(min) = icon.width;

                Originally posted by RedSon
                Also, I would use this formula
                Code:
                r(min) = n · icon.width / ( sqroot(2) · pi )
                but the screen size is so small having 5 or more icons creates a great amount of clutter. Is there a way to modify this such that r(min) can be calculated for n > 1?
                the formula is an approximation of the circumference calculation, which will give large deviations for small n.
                Last edited by Dormilich; Jan 28 '09, 03:30 PM. Reason: adding another quote

                Comment

                • Dormilich
                  Recognized Expert Expert
                  • Aug 2008
                  • 8694

                  #9
                  Originally posted by RedSon
                  Also would either of you be willing to do some code review on the project I linked to in post 3?
                  If I don't have to do it until next week, I'll try my best.

                  Comment

                  • RedSon
                    Recognized Expert Expert
                    • Jan 2007
                    • 4980

                    #10
                    You don't have to do it until whenever you want to do it. There is no project schedule for this, it is a hobby of mine.

                    Comment

                    • RedSon
                      Recognized Expert Expert
                      • Jan 2007
                      • 4980

                      #11
                      Originally posted by Dormilich
                      Code:
                      Math.Cos(factor * i + 1)
                      57° 17′ 44.8″ = 1 (rad),
                      like usual in maths, if you add in y = f(x) a value to x, you shift the function by –x
                      Of course, that didn't even occur to me! I will have to make a fix for that, since I would like it to start at 0.

                      Comment

                      • Dormilich
                        Recognized Expert Expert
                        • Aug 2008
                        • 8694

                        #12
                        that's good.

                        if you would in turn have a look at my PHP code........ (though I need to find a place to post the code first)

                        Comment

                        • RedSon
                          Recognized Expert Expert
                          • Jan 2007
                          • 4980

                          #13
                          I would look at it, however I find PHP code to be much more cryptic than C#, so I am not sure how useful I will be. :(

                          Comment

                          • Dormilich
                            Recognized Expert Expert
                            • Aug 2008
                            • 8694

                            #14
                            it's more about programm design than actual coding (I know that my PHP knowledge is above forum average, but that doesn't mean I can't overlook some crucial points, especially since I'm new to OOP coding)

                            Comment

                            • RedSon
                              Recognized Expert Expert
                              • Jan 2007
                              • 4980

                              #15
                              Well, just got to find a place to put it ;-)

                              Comment

                              Working...