Take the 2-minute tour ×
Mathematics Stack Exchange is a question and answer site for people studying math at any level and professionals in related fields. It's 100% free, no registration required.

Given a circular sector defined by sweeping from a 'start' to a 'stop' angle (see diagram below) and a radius, how do you compute the bounds of the rectangle that fits to the edges of the sector? Additionally, assuming that the top left corner of the rectangle is at (0, 0), where is the center of the arc within the rectangle?

The diagram below should clarify all the assumptions in my situation and gives two examples of the sectors I can have. The red rectangle is the rectangle of interest. Please note the particular challenges:

  • Sweeping direction is always clockwise, and sectors can extend past 180 degrees. Naming convention (i.e. 0 degrees is at 3 o'clock) as shown.

  • Angles can wrap around +/- 180 degrees; -10 and 190 are equivalent, but this means that any calculations of angular distances (if needed) need to account for that. For example, with a start angle of 170 and a stop of -170, the angle of the sector is only 20, not -340 (which is what a blind application of 'stop' - 'start' would give you)

  • One final complication: the coordinate system I am working in has the origin at the top left rather than bottom left, so the bottom right corner of the rectangle will have positive x and y coordinates.

Circular sector illustration

If anyone's curious, this is for computer graphics in a user interface. The circular sector is actually broken into a 'wheel' of menu options, and I need its size to be able to lay out other UI elements around it. The position of the center of the circular sector is required to determine whether a mouse click is within an element or not.

Thank you!

share|improve this question
2  
+1 for a well-asked question –  Chris Taylor Jun 14 '11 at 15:14

2 Answers 2

up vote 2 down vote accepted

Here's some R code that solves the problem. Translate to the language of your choice. It implements the solution in Ross Millikan's answer, so upvote that if this is useful. The function getCoords takes an interval (which is a vector whose first component is the start angle and whose second is the end angle) and returns a vector of four components in the form (top, left, bottom, right).

The coordinate system takes the top left corner to be (0,0) and the bottom right corner to be (1,1) so you should scale the output appropriately.

Example usage:

> interval <- c(315, 45)
> getCoords(interval)
[1] 0.1464466 0.5000000 0.8535534 1.0000000

This sets the interval to start at 315 degrees (equivalently -45 degrees) and end at 45 degrees. The top and bottom of the resulting rectangle are 0.146... and 0.854... and the left and right coordinates are 0.5 (because the centre of the wedge is at 0.5) and 1.0 (because this sector includes the rightmost point of the circle).

Code:

isInInterval <- function(theta, interval) {
    theta <- theta %% 360
    i <- interval[1] %% 360
    f <- interval[2] %% 360  #set all values to be in the range [0, 360)
    if (i < f) {
        return (theta >= i && theta <= f)
    } else {
        return (!(theta < i && theta > f))
    }
}

getXcoord <- function(theta) {
    return((1+cos(theta * 2*pi / 360))/2)
}

getYcoord <- function(theta) {
    return((1+sin(theta * 2*pi / 360))/2)
}

getCoords <- function(interval) {
    i <- interval[1]
    f <- interval[2]

    xi <- getXcoord(i)
    yi <- getYcoord(i)
    xf <- getXcoord(f)
    yf <- getYcoord(f)

    is0   <- isInInterval(0, interval)
    is90  <- isInInterval(90, interval)
    is180 <- isInInterval(180, interval)
    is270 <- isInInterval(270, interval)

    if (is0)   {right <- 1}  else {right <- max(xi, xf, 0.5)}
    if (is90)  {bottom <- 1} else {bottom <- max(yi, yf, 0.5)}
    if (is180) {left <- 0}   else {left <- min(xi, xf, 0.5)}
    if (is270) {top <- 0}    else {top <- min(yi, yf, 0.5)}

    return(c(top, left, bottom, right))
}
share|improve this answer
    
Great, thanks! This worked perfectly to get the size of the rectangle. With that I think I can work out how to determine the arc's center position (the 2nd half of the question) later today. Once I sort that out, I'll mark this as the accepted answer and close off this question. –  Steve Haley Jun 14 '11 at 16:19
    
Indeed, getting the center of the sector (relative to the top left corner) is trivial once the calculations above have been done. xCenter = 0.5 - left, and yCenter = 0.5 - top. Thanks again! –  Steve Haley Jun 14 '11 at 22:49

Your output is the coordinate of each side of the box. I would start by checking whether $0^{\circ},90^{\circ},180^{\circ},270^{\circ}$ are included. For each one that is, you have one coordinate. Any other coordinate has to be either the center of the circle (if the arc goes from $70^{\circ}$ to $110^{\circ}$, for example) or the end point of one radius, so just check those three.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.