Reputation: 7205
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
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