nordi Posted May 3, 2014 Share Posted May 3, 2014 (edited) Hey So, I am making a circular menu, but I am stuck with the button position. I created my circular menu (with the button, background, etc.) on Photoshop, then split each button of the circular menu (on photoshop). Now on visual studio, I am assigning a PictureBox for each button, but: How can I calculate the X & Y position for each button ? Because right now, the only solution I see is to try manually values, but it won't look good (and not be really circular ...) I am using a base circle in the middle, which the location is: And the other buttons of the menu, are supposed to be around it. Thanks. Edited August 16, 2014 by nordi Link to comment https://gtaforums.com/topic/705894-c-circular-menu/ Share on other sites More sharing options...
pedro2555 Posted May 3, 2014 Share Posted May 3, 2014 (edited) Somewhere on this forum I've explained this process already. If I understood correctly, what you want is a Point (x an y), for a given radius and angle, is that correct ? If yes, that is achieved with the trigonometric functions Sin and Cos, which are available within the Math class in .NET. Basically for a given point 'a,b' at the center of a circumference of radius 'c', to get a point 'd,e' on the circumference perimeter at angle 'f', you would use: d = a + (sin(f) * c)e = b + (cos(f) * c) Note that 'f' is expressed in radians. radians = degrees / 180 Point coordinates are expressed as 'x,y', for the corresponding axis. Don't take my word for this, I haven't tested before posting, and so, I provide this information as is. Edited May 3, 2014 by pedro2555 nordi 1 Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065311622 Share on other sites More sharing options...
Silent Posted May 4, 2014 Share Posted May 4, 2014 Note that 'f' is expressed in radians. radians = degrees / 180 You forgot to multiply by Pi Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065314676 Share on other sites More sharing options...
nordi Posted May 4, 2014 Author Share Posted May 4, 2014 Somewhere on this forum I've explained this process already. If I understood correctly, what you want is a Point (x an y), for a given radius and angle, is that correct ? If yes, that is achieved with the trigonometric functions Sin and Cos, which are available within the Math class in .NET. Basically for a given point 'a,b' at the center of a circumference of radius 'c', to get a point 'd,e' on the circumference perimeter at angle 'f', you would use: d = a + (sin(f) * c)e = b + (cos(f) * c) Note that 'f' is expressed in radians. radians = degrees / 180 Point coordinates are expressed as 'x,y', for the corresponding axis. Don't take my word for this, I haven't tested before posting, and so, I provide this information as is. Thanks, that's what I needed ! Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065315414 Share on other sites More sharing options...
nordi Posted May 4, 2014 Author Share Posted May 4, 2014 (edited) The entire circle is 365px * 365px (12.88cm * 12.88cm). I think the problem is from sin(f), I am using the wrong value ... Edited May 5, 2014 by nordi Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065316662 Share on other sites More sharing options...
pedro2555 Posted May 4, 2014 Share Posted May 4, 2014 (edited) @Silent I forgot pi indeed, the actual conversion goes as: radians = pi * degrees / 180 @nordi Please re-check the degree to radian calculation with the formula above. Also your calculations seem wrong. Where you have: double X2 = Game.Resolution.Width / 2f + (Math.Sin(15 / 180 * Math.PI) * 45);double Y2 = Game.Resolution.Height / 2f + (Math.Cos(15 / 180 * Math.PI) * 45); I believe you want to place something at 15 degrees, if so try the snippet bellow, double X2 = menu.Location.X + Math.Sin(Math.PI * 15 / 180) * 45;double Y2 = menu.Location.Y + Math.Cos(Math.PI * 15 / 180) * 45; also, Game.Resolution.Width / 2f is redundant, since it is first calculated and store in menu.Location.X. And since 15 degrees is static, you should calculate on the side and pass the radians hardcoded to void unnecessary bottlenecks. Edited May 5, 2014 by pedro2555 Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065317338 Share on other sites More sharing options...
nordi Posted May 5, 2014 Author Share Posted May 5, 2014 (edited) @nordi Please re-check the degree to radian calculation with the formula above. Also your calculations seem wrong. Where you have: double X2 = Game.Resolution.Width / 2f + (Math.Sin(15 / 180 * Math.PI) * 45);double Y2 = Game.Resolution.Height / 2f + (Math.Cos(15 / 180 * Math.PI) * 45); I believe you want to place something at 15 degrees, if so try the snippet bellow, double X2 = menu.Location.X + Math.Sin(Math.PI * 15 / 180);double Y2 = menu.Location.Y + Math.Cos(Math.PI * 15 / 180); also, Game.Resolution.Width / 2f is redundant, since it is first calculated and store in menu.Location.X. After doing some research on google, it appears, Cos have to be used for the X value, and Sin for the Y value. After spending time, trying different values & doing some edit to the formula you provided, I managed to get the right degrees for the button position, the only problem left is the button positions: For some reason the X & Y of the base circle seems to be wrong (A & B, on your formula), but the weirdest thing is that 2 buttons are at the correct position, while the other 3 buttons are misplaced (i'm using the same formula for all of the buttons though, which should give me whether the right position for all buttons or the wrong position for all ...). Here is the current code: (X3 & Y3 ; X5 & Y5 are at the correct position, but others are not) Edited May 5, 2014 by nordi Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065320499 Share on other sites More sharing options...
pedro2555 Posted May 5, 2014 Share Posted May 5, 2014 (edited) I told you I haven't tested anything, I went for memory and it has been a long time since I made use of this (school time actually). I think you have no clue what trigonometry is, I will not give a full blow explanation, but the following picture should help you: So, yes, from the table Cosine is Y while Sine is X. My bad there. You should also note that they return a value for a radius of 1 with center at 0,0. That's why you have to sum the actual center and multiply by the actual radius. The following code is tested and draws a perfect circle // Draw a circle (values in pixels)// Circle center pointPoint center = new Point(canvas.Width / 2, canvas.Height / 2);// Center radiusint radius = 30;// Last used point for drawing a linePoint lastPoint = Point.Empty;// Current point being calculatedPoint currentPoint = Point.Empty;for (int i = 0; i < 360; i++){ // Calculate a new point currentPoint = new Point( (int)(center.X + Math.Cos(Math.PI * i / 180) * radius), // Calculate X (int)(center.Y + Math.Sin(Math.PI * i / 180) * radius)); // Calculate Y // If we a have last point, draw a line if (lastPoint != Point.Empty) e.Graphics.DrawLine(new Pen(Color.Black), lastPoint, currentPoint); lastPoint = currentPoint;} The icons are offset because you are using point based on screen but their parent is the form. If you draw them at 0,0 they should appear on the top left corner of the form and not the screen. Edited May 5, 2014 by pedro2555 LordOfTheBongs 1 Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065320572 Share on other sites More sharing options...
nordi Posted May 5, 2014 Author Share Posted May 5, 2014 (edited) I told you I haven't tested anything, I went for memory and it has been a long time since I made use of this (school time actually). I think you have no clue what trigonometry is, I will not give a full blow explanation, but the following picture should help you: So, yes, from the table Cosine is Y while Sine is X. My bad there. You should also note that they return a value for a radius of 1 with center at 0,0. That's why you have to sum the actual center and multiply by the actual radius. The following code is tested and draws a perfect circle // Draw a circle (values in pixels)// Circle center pointPoint center = new Point(canvas.Width / 2, canvas.Height / 2);// Center radiusint radius = 30;// Last used point for drawing a linePoint lastPoint = Point.Empty;// Current point being calculatedPoint currentPoint = Point.Empty;for (int i = 0; i < 360; i++){ // Calculate a new point currentPoint = new Point( (int)(center.X + Math.Cos(Math.PI * i / 180) * radius), // Calculate X (int)(center.Y + Math.Sin(Math.PI * i / 180) * radius)); // Calculate Y // If we a have last point, draw a line if (lastPoint != Point.Empty) e.Graphics.DrawLine(new Pen(Color.Black), lastPoint, currentPoint); lastPoint = currentPoint;} The icons are offset because you are using point based on screen but their parent is the form. If you draw them at 0,0 they should appear on the top left corner of the form and not the screen. I do understand how it works, especially after reading this: http://www.wikihow.com/Calculate-the-Radius-of-a-Circle But, I can't get it to work ! Here is how I understand things, based on your last code: center, is the coordinates of the center of the circle, which on my code is menu.Location.X & menu.Location.Y ; i on your code, is the coordinates of the point(x & y) on the circle, which is my X1, Y1 ; X2, Y2 ; X3,Y3 ; etc. radius: is the distance between the center of the circle and the point on the circle, which on my code is 38. After multiple try, I managed to get the correct i, and the correct radius because the button are well placed regarding these 2 values. So obviously, the problem can only come from the circle center coordinates (because the angle, and radius is fine, but the position on the circle isn't). Plus I'm using exactly the same formula as you do, so it can't be a code / formula error . My form position is: the Game resolution /2, and the menu position (the center of the circle) is the form position /2 fire extinguisher but you can't see it very well it's on the right bottom) Edited May 5, 2014 by nordi Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065321034 Share on other sites More sharing options...
pedro2555 Posted May 5, 2014 Share Posted May 5, 2014 (edited) We are complicating this. Take a look at following code, it is a windows form project, with a panel called canvas. The following is the method Load(): // canvas is the parent container of our pictures, so parent and canvas are the same thing and in your case are the form itself// Center of the circle is at parent.width/2, parent.height/2// Circle radius is 38// Each quadrant image is 38x38// Quadrants ids go like this//// 2 |1// ___|____// 3 |4// |//// Note: // 1. There is no need to wrap all images inside an image box, you can simply place the four image boxes on the form itself. This isn't HTML ;D.// 2. All elements have their point 0 at the top left corner, not their center// 3. Since it is only 4 images this can be very much simple// Basically you have for diferent locations:// 1 - 0,-1// 2 - -1,-1// 3 - -1,0// 4 - 0,0// Canvas centerPoint center = new Point( canvas.Width / 2, canvas.Height / 2);// circle radiusint radius = 38;// the easieast is the fourth quadrant, the image box should have it's top left corner at point 0 of the circlePictureBox fourthQuadrant = new PictureBox();fourthQuadrant.Location = center;fourthQuadrant.Size = new Size(38, 38); // 0,0fourthQuadrant.BorderStyle = BorderStyle.FixedSingle;canvas.Controls.Add(fourthQuadrant);// the first quadrant should have axis X of it's location also at 0, but the Y axis must be shifted to the edge of the circlePictureBox firstQuadrant = new PictureBox();firstQuadrant.Location = new Point( center.X, center.Y - radius); firstQuadrant.Size = new Size(38, 38);firstQuadrant.BorderStyle = BorderStyle.FixedSingle;canvas.Controls.Add(firstQuadrant);// the remaining quadrants are the mirrors// second quadrant is the mirror of the firstPictureBox secondQuadrant = new PictureBox();secondQuadrant.Location = new Point( center.X - radius, center.Y - radius);secondQuadrant.Size = new Size(38, 38);secondQuadrant.BorderStyle = BorderStyle.FixedSingle;canvas.Controls.Add(secondQuadrant);// the third is the mirror of the fourtPictureBox thirdQuadrant = new PictureBox();thirdQuadrant.Location = new Point( center.X - radius, center.Y);thirdQuadrant.Size = new Size(38, 38);thirdQuadrant.BorderStyle = BorderStyle.FixedSingle;canvas.Controls.Add(thirdQuadrant); Edited May 5, 2014 by pedro2555 nordi 1 Link to comment https://gtaforums.com/topic/705894-c-circular-menu/#findComment-1065321292 Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now