L Tyrone
L Tyrone

Reputation: 7205

Create sequence of degrees and radii that may contain 0 (degrees)

I am needing to create a path between two points for which distance and degrees are known, and then convert the result to Cartesian coordinates using R. The origin for both points is 0,0. The radii always vary in length. The direction is always anti-clockwise.

I have been unable to work out how to do the degrees sequence as the range sometimes may include 0°. The start and end degrees will vary so I need method that can handle any range <= 180°. In other words, the difference between the start and end angle will never exceed 180°.

The issue is illustrated in the code below:

rad <- seq(943.0975, 939.5975, length.out = 1000)
deg <- seq(67.8352, 247.8352, length.out = 1000)

The rad vector works correctly but the deg vector is incorrect as it ends up following a clockwise direction. Doing a descending seq() means it doesn't cross 0°.

How is a range of degree values that contains 0° handled in this instance?

Upvotes: 0

Views: 71

Answers (1)

L Tyrone
L Tyrone

Reputation: 7205

Unable to find a concise method, this is how I handled the issue. It involves a process that generates two vectors for degrees - one for everything to the "left" of 0° and one for everything to the "right" of 0°. It is "messy" around the 0° in that the difference between the two values directly to the left and right of 0° may not be == turni, but given the size of endturnp the issue is not perceptible. This code only works if degdiff <= 180°.

Declared variables

degA <- 67.8352   # Start point degrees
radA <- 943.0975  # Start point radius
degB <- 247.8352  # End point degrees
radB <- 939.5975  # End point radius
endturnp <- 2030  # Number of points to plot between start and end point

Derived variables

degdiff <- (outdegs - outdege + 180) %% 360 - 180     # Degrees difference between start and end
degdiff <- ifelse(degdiff < 0, degdiff * -1, degdiff) # Convert to positive number if negative
turni <- degdiff / endturnp                           # Get degrees increment between degA and degB based on "endturnp"

Generate degree vector from degA to degB

if(degA < degB) { # If range includes 0 degrees
   leftlen <- 0:floor((360 - degB) / turni) # Return length vector for degrees > 180 & < 360
   leftdeg <- sort(degB + (leftlen * turni), decreasing = T) # Calculate degrees
   rightlen <- 0:floor(degA/turni) # Return length vector
   rightdeg <- degA - (turni * rightlen) # calculate degree
   indexdeg <- append(rightdeg,leftdeg) # Combine degrees vectors
   } else {
      indexdeg <- seq(degA, degB, length.out = endturnp) # Create index
}

Generate radii vector from degA to degB

indexrad <- seq(radA, radB, length.out =  length(indexdeg))

Combine radii and degrees vectors and calculate xy coordinates

arcpath <- data.frame(rad = indexrad,
                      deg = indexdeg,
                      x = NA,
                      y = NA) 

arcpath$x <- arcpath$rad * sin(pi * 2 * arcpath$deg / 360)
arcpath$y <- arcpath$rad * cos(pi * 2 * arcpath$deg / 360)

And finally, plot result

ggplot() +
  geom_path(data = arcpath, aes(x = x, y = y),
        linewidth = .4,
        lineend = "square")

Upvotes: 0

Related Questions