3

I have a circular arena which I have divided into a number of equal-sized 'cells' using a grid-like arrangement of concentric circles and line segments (in grey below) and also a series of x,y coordinates (plotted as a line in black below).

sampleFig

I was wondering what would be the best method (preferably using R) to find out which 'cell' each point is in ? I guess I could test to see which circle each point lies in by its distance from the centrepoint, and then which sector the point lies in by its angle from the centrepoint, but this seems rather laborious and inelegant..

This question bears some similarity to this one, except that I'm using circular lines to demarcate grid cells rather than linear lines.

1

To me, the simplest approach is to probably convert your XY datapoints to the polar coordinate system that defines your circular 'arena'.

Be sure to convert your XY coordinates such that the center of your circle is the origin of your Cartesian grid before converting to polar coordinates. Almost all math texts would provide these straightforward conversion equations, but this Wikipedia entry would definitely suffice.

Each of your equal area sectors are bounded by specific values for R and theta in the polar coordinate system.

Once you convert your Cartesian coordinates, simply round the calculated polar coordinates for each of your points to the nearest R and theta values that define your arena sectors.

This solution may be 'inelegant', but it strikes me as being about as straightforward as you could get.

  • Thank you @UncoolE, I haven't came across the polar coordinate before -- this looks right up the street I need! – jogall Jul 11 '14 at 23:23
1

I thought I'd answer this myself just in case anyone else with a similar problem ever stumbles on this.

Using the above advice on converting my Cartesian coordinates to polar coordinates, I've made a function which calculates a minimum enclosing circle around the x,y coordinates, and divides this circle into a user-defined number of 'grid' cells with equal area, before assigning a unique ID to each cell and determining which cell each x,y point is in.

Here's the function, where x and y are both arrays containing the raw x,y coordinates, and n_radials and n_slices are the desired number of longitudinal and radial sectors to divide the circular arena into.

require(shotGroups)

getCellID <- function(x, y, n_radials, n_slices) {

    # first, calculate radii of all radials
    #--------------------------------------
    xy <- matrix(c(x, y), ncol=2)
    xy <- na.omit(xy)

    #get minimum enclosing circle to find outer radius
    circle <- getMinCircle(xy)
    midX <- circle$ctr[1]
    midY <- circle$ctr[2]
    outer_radius <- circle$rad

    #calculate radii of each internal radial
    radii <- c()
    for(i in 1:n_radials){
        radii_i <- outer_radius * sqrt(i/n_radials)
        radii <- rbind(radii, radii_i)
    }

    # then, convert x,y to polar coordinates
    #---------------------------------------

    #normalise raw x,y coordinates so relative to centre of circle
    x <- x - midX
    y <- y - midY

    #convert Cartesian coordinates to polar
    polar_radii <- sqrt(x^2 + y^2)
    polar_theta <- atan2(y, x) / pi * 180

    # and lastly, determine which 'grid' cell each point lies in
    #-----------------------------------------------------------

    #determine which SLICE
    slice_breaks <- seq(-180, 180, 360 / n_slices)
    sliceID <- cut(polar_theta, slice_breaks)
    levels(sliceID) <- c(1:n_slices)

    #determine which RADIAL
    radial_breaks <- c(0, radii)
    radialID <- cut(polar_radii, radial_breaks)
    levels(radialID) <- c(1:nrow(radii))

    #determine which CELL
    cellID <- n_slices * (as.numeric(radialID) - 1) + as.numeric(sliceID)

    #-------
    # Output
    return(cellID)

}

I'd still be interested in any critical insight or ways to improve this function!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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