Rotate graph by angle

graph, matrix, r, rotation

Solution

Like this?

#read in X and Y as vectors
M <- cbind(X,Y)
#plot data
plot(M[,1],M[,2],xlim=c(0,1200),ylim=c(0,1200))
#calculate rotation angle
alpha <- -atan((M[1,2]-tail(M,1)[,2])/(M[1,1]-tail(M,1)[,1]))
#rotation matrix
rotm <- matrix(c(cos(alpha),sin(alpha),-sin(alpha),cos(alpha)),ncol=2)
#shift, rotate, shift back
M2 <- t(rotm %*% (
  t(M)-c(M[1,1],M[1,2])
  )+c(M[1,1],M[1,2]))
#plot
plot(M2[,1],M2[,2],xlim=c(0,1200),ylim=c(0,1200))

Edit:

I'll break down the transformation to make it easier to understand. However, it's just basic linear algebra.

plot(M,xlim=c(-300,1200),ylim=c(-300,1200))
#shift points, so that turning point is (0,0)
M2.1 <- t(t(M)-c(M[1,1],M[1,2]))
points(M2.1,col="blue")
#rotate
M2.2 <- t(rotm %*% (t(M2.1)))
points(M2.2,col="green")
#shift back
M2.3 <- t(t(M2.2)+c(M[1,1],M[1,2]))
points(M2.3,col="red")

Problem

I have multiple matrices filled with the x and y coordinates of multiple points in 2D space that make up a graph. The matrices look something like this x1 x2 x3 x4 ... y1 y2 y3 y4 ... A possible graph looks something like this What I want to do is rotate the graph around point A so that the line between the points A and B are parallel to the X-Axis. My idea was to treat the line AB as the hypothenuse of a right-triangle, calculate α (the angle at point A) and rotate the matrix for this graph by it using a rotation matrix. What I did so far is the following ``` #df is the subset of my data that describes the graph we're handling right now, #df has 2 or more rows beginx=df[1,]$xcord #get the x coordinate of point A beginy=df[1,]$ycord #get the y coordinate of point A endx=df[nrow(df)-1,]$xcord #get the x coordinate of point B endy=df[nrow(df)-1,]$ycord #get the y coordinate of point B xnow=df$xcord ynow=df$ycord xdif=abs(beginx-endx) ydif=abs(beginy-endy) if((xdif != 0) & (ydif!=0)){ direct=sqrt(abs((xdif^2)-(ydif^2))) #calculate the length of the hypothenuse sinang=abs(beginy-endy)/direct angle=1/sin(sinang) if(beginy>endy){ angle=angle }else{ angle=360-angle } rotmat=rot(angle) # use the function rot(angle) to get the rotation matrix for # the calculated angle A = matrix(c(xnow,ynow),nrow=2,byrow = TRUE) # matrix containing the graph coords admat=rotmat%*%A #multiply the matrix with the rotation matrix } ``` This approach fails because it isn't flexible enough to always calculate the needed angle with the result being that the graph is rotated by the wrong angle and / or in the wrong direction. Thanks in advance for reading and hopefully some of you can bring some fresh ideas to this Edit: Data to reproduce this can be found here X-Coordinates Y-Coordinates Not sure how to provide the data you've asked for, I'll gladly provide it in another way if you specify how you'd like it

Original source