Simplified equation to determine the coordinates of a rotated rectangle whose length is modified?

385 Views Asked by At

I would like to attempt what the following site performs with a rotated rectangle: http://www.mathopenref.com/coordrectangle.html

I am provided with the angle of rotation, and all initial vertex coordinates. Whenever I drag a vertex, I am able to automatically update the values of that coordinate, but I want the two closest vertices to the "dragged" vertex to change positions accordingly as well. So in the given case of seeking out the coordinate values of dx,dy I need to figure out individual equations for solving for dx and dy.

2

There are 2 best solutions below

7
On BEST ANSWER

Call the angle $\theta$, the dragged point $D$ and the fixed point $F$. Write the equation for the line through $F$ with slope $m= \tan(\theta)$ and the equation for the line through $F$ with slope $\tan(\theta+\frac{\pi}{2})= -\frac{1}{m}$. Do the same for the lines through $D$. You will get the following four equations: $$y=mx+(y_F-mx_F)\tag{1}$$ $$y=-\frac{1}{m}x+(y_F+\frac{1}{m}x_F)\tag{2}$$ $$y=mx+(y_D-mx_D)\tag{3}$$ $$y=-\frac{1}{m}x+(y_D+\frac{1}{m}x_D)\tag{4}$$

Edit

The point of intersection between line $(1)$ and line $(4)$, call it point $A$, is one corner. We find it by subtracting $(4)$ from $(1)$, giving: $$0=mx+\frac{1}{m}x + (y_F-mx_F) - (y_D+\frac{1}{m}x_D)$$ Rearranging we get $$x_A = (\frac{m}{m^2+1})(y_D+\frac{1}{m}x_D - y_F+mx_F)$$ And using $(1)$ we get $$y_A=mx_A+(y_F-mx_F)$$ That is point $A$. In the same way, using $(2)$ and $(3)$ we find the other corner, point $B$: $$x_B = (\frac{m}{m^2+1})(y_F+\frac{1}{m}x_F - y_D+mx_D)$$ $$y_B=mx_B+(y_D-mx_D)$$

If $\theta$ is a multiple of $\frac{\pi}{2}$ you need to handle this (easier) case separately.

0
On

Let's name the fixed vertex $( x_0 , y_0 )$, the moving vertex $( x_2 , y_2 )$, the vertex in between $( x_1 , y_1 )$ (in direction of $w$), and the final vertex $( x_3 , y_3 )$ (in direction of $h$). (The vertices are numbered in clockwise or counterclockwise order.)

One way to define the above vertices relative to the fixed vertex using "width" $w$, "height" $h$, and rotation angle $\theta$ is $$\begin{cases} x_1 = x_0 + w \cos \theta \\ y_1 = y_0 - w \sin \theta \end{cases} ,\; \begin{cases} x_2 = x_0 + w \cos \theta + h \sin \theta \\ y_2 = y_0 - w \sin \theta + h \cos \theta \end{cases} , \; \begin{cases} x_3 = x_0 + h \sin \theta \\ y_3 = y_0 + h \cos \theta \end{cases}$$ Note that if you initially know only the vertices, you can use $$\begin{cases} w = \sqrt{ ( x_1 - x_0 )^2 + ( y_1 - y_0 )^2 } \\ h = \sqrt{ ( x_3 - x_0 )^2 + ( y_3 - y_0 )^2 } \\ \theta = \operatorname{atan2}( y_1 - y_0 ,\, x_1 - x_0 )\end{cases} \tag{1}\label{1}$$ where $\operatorname{atan2}(y, x)$ is equivalent to $\operatorname{atan}(y / x)$ except that it considers the quadrant (signs of $x$ and $y$ separately) too, covering all angles $\theta$. $\operatorname{atan2}(y, x)$ is provided by most programming languages.

If the vertex $(x_2 , y_2)$ is moved by $(x_\Delta , y_\Delta)$, the width changes by $w_\Delta$ and height by $h_\Delta$: $$\begin{cases} x_0 + w \cos \theta + h \sin \theta + x_\Delta = x_0 + (w + w_\Delta) \cos \theta + (h + h_\Delta) \sin \theta \\ y_0 - w \sin \theta + h \cos \theta + y_\Delta = y_0 - (w + w_\Delta) \sin \theta + (h + h_\Delta) \cos \theta \end{cases}$$ which simplifies to $$\begin{cases} x_\Delta = w_\Delta \cos \theta + h_\Delta \sin \theta \\ y_\Delta = w_\Delta \sin \theta - h_\Delta \cos \theta \end{cases} \tag{2}\label{2}$$ Solving $\eqref{2}$ for $w_\Delta$ and $h_\Delta$ we get $$\begin{cases} w_\Delta = x_\Delta \cos \theta + y_\Delta \sin \theta \\ h_\Delta = x_\Delta \sin \theta - y_\Delta \cos \theta \end{cases} \tag{3}\label{3}$$


It is easier to manipulate the vertices directly, if don't need to manipulate the $w$, $h$, $\theta$ directly. You can use $\eqref{1}$ to obtain them from the vertices when needed.

When the dragging starts, rename the vertices in clockwise or counterclockwise order so that $( x_0 , y_0 )$ is he fixed vertex, $( x_2 , y_2 )$ is the moving vertex, and $( x_1 , y_1 )$ and $( x_3 , y_3 )$ are the vertices in between. Then, calculate constants $$\begin{array}{c} w_x = x_1 - x_0 \\ w_y = y_1 - y_0 \\ h_x = x_3 - x_0 \\ h_y = y_3 - y_0 \\ \end{array}$$and$$d = w_x h_y - w_y h_x = ( x_1 - x_0 ) ( y_3 - y_0 ) - ( y_1 - y_0 ) ( x_3 - x_0 )$$

Then, whenever the moving vertex is dragged from $( x_2 ,\, y_2 )$ to $( x_2 + x ,\, y_2 + y )$, the two other vertices become $$\begin{cases} x_1 = x_0 + w_x C_1 \\ y_1 = y_0 + w_y C_1 \end{cases}, \; C_1 = \frac{ h_y ( w_x + x ) - h_x ( w_y + y ) }{d}$$ and $$\begin{cases} x_3 = x_0 + h_x C_3 \\ y_3 = y_0 + h_y C_3 \end{cases}, \; C_3 = \frac{ w_x ( h_y + y ) - w_y ( h_x + x ) }{d}$$


Note that rotation can also be achieved using the vertices alone.

When the rotation starts, rename the vertices in counterclockwise order (clockwise if your $x$ increases right and $y$ down), with $( x_0 , y_0 )$ being the fixed vertex, $( x_2 , y_2 )$ the vertex the user "drags", and $( x_1 , y_1 )$ and $( x_3 , y_3 )$ the vertices in between. First, calculate constants $$\begin{cases} w = \sqrt{ (x_1 - x_0)^2 + (y_1 - y_0)^2 } \\ h = \sqrt{ (x_2 - x_1)^2 + (y_2 - y_1)^2 } \\ L = \sqrt{ (x_2 - x_0)^2 + (y_2 - y_0)^2 } \\ C_1 = w^2 / L \\ C_2 = h^2 / L \\ C_3 = w h / L \end{cases}$$

Whenever the mouse is at $(x_M , y_M)$, the vertices become $$\begin{cases} x_1 = x_0 + x C_1 - y C_3 \\ y_1 = y_0 + x C_3 + y C_1 \\ x_2 = x_0 + x L \\ y_2 = y_0 + y L \\ x_3 = x_0 + x C_2 + y C_3 \\ y_3 = y_0 - x C_3 + y C_2 \end{cases}, \qquad \begin{cases} x = (x_M - x_0) / \sqrt{(x_M - x_0)^2 + (y_M - y_0)^2} \\ y = (y_M - y_0) / \sqrt{(x_M - x_0)^2 + (y_M - y_0)^2} \end{cases}$$ This keeps the distance of the vertices from vertex $( x_0 , y_0 )$ constant, with mouse on the line between vertices $( x_0 , y_0 )$ and $( x_2 , y_2 )$. Note that if the mouse is at $( x_0 , y_0 )$, $x$ and $y$ are undefined, and you should then simply not update the vertex coordinates.