J'ai une réponse partielle. A partir de:Maths question sur la rotation des points dans .Net
newHeight = Taille * cos (radians) + Largeur * sin (radians)
newWidth = Taille * sin (radians) + Largeur * cos (radians)
Je peux inverser les équations pour obtenir :
temp = SQR (cos (radians)) - SQR (sin (radians))
Hauteur = newHeight * cos (radians) - newWidth * sin (radians)/Temp
width = NewWidth * cos (radians) - newHeight * sin (radians)/temp
Les équations ci-dessus ne se comportent que pour les plages d'angles 0-28, 62-90, 180-208 et 242-270. Hors de ces plages, les limites calculées sont trop grandes et entraînent un débordement à 45, 135, 225 et 315.
Je suppose que je dois détecter le quadrant dans lequel je suis et modifier légèrement les équations. Des idées?
J'ai eu du mal à être clair sur ce qu'est exactement ce que je demande dans cette question si nous espérons l'exemple suivant effacera les choses.
L'exemple prend un carré de 100x100, le fait pivoter de 12 degrés et ajoute 100 à la largeur. Qu'est-ce que je veux faire est de trouver les dimensions d'un rectangle qui, après avoir tourné de 12 degrés se traduira par le même rectangle, sans ajouter les 100 à la largeur après:
Les rectangles dessinés sont les limites de la forme en rotation et non la forme elle-même:
Dim radAngle = Math.PI * 12/180.0R
Dim widthChange = 100
Dim b2 = New RectangleF(200, 200, 100, 100)
b2 = GetBoundsAfterRotation(b2, radAngle)
b2.Width += widthChange
g.DrawRectangle(Pens.Red, ToRectangle(b2))
Dim offsetY = 21
Dim offsetX = -7
b2 = New RectangleF(200, 200, 100 + widthChange - offsetX, 100 - offsetY)
b2 = GetBoundsAfterRotation(b2, radAngle)
b2.X += CInt(offsetX/2)
b2.Y += CInt(offsetY/2)
g.DrawRectangle(Pens.Green, ToRectangle(b2))
par piste et erreur je trouve les valeurs de offsetX et offsetY qui se traduiront dans le même rectangle pour ce cas particulier: a tourné 100x100 carré de 12 degrés avec 100 ajouté à la largeur . Je suis sûr que cela implique le péché, cos ou les deux quelque part mais le gel du cerveau m'empêche de construire la formule. ETA: Dans ce cas j'augmente la largeur, mais j'ai besoin d'une solution générale pour la largeur, la hauteur ou les deux changements. ETA2: Dans ce cas, la taille du rectangle résultant était de 218,6 x 118,6. Pour obtenir ces limites après la rotation par 12 degrés, les limites du rectangle de départ étaient d'environ 207 x 79.
Original:
J'utilise les éléments suivants, standard, routines pour obtenir les limites d'une image après a été tourné d'un angle spécifié, autour de son centre.Les limites sont décalées de sorte que le centre de l'image est toujours au même endroit:
Public Function GetBoundsAfterRotation(ByVal imageBounds As RectangleF, ByVal radAngle As Double) As RectangleF
Dim w = imageBounds.Width
Dim h = imageBounds.Height
Dim rotationPoints As PointF() = {New PointF(0, 0), New PointF(w, 0), New PointF(0, h), New PointF(w, h)}
RotatePoints(rotationPoints, New PointF(w/2.0F, h/2.0F), radAngle)
Dim newBounds = GetBoundsF(rotationPoints)
Dim x = imageBounds.X + newBounds.X //Offset the location to ensure the centre point remains the same
Dim y = imageBounds.Y + newBounds.Y
Return New RectangleF(New PointF(x, y), newBounds.Size)
End Function
//
Public Shared Sub RotatePoints(ByVal pnts As PointF(), ByVal origin As PointF, ByVal radAngle As Double)
For i As Integer = 0 To pnts.Length - 1
pnts(i) = RotatePoint(pnts(i), origin, radAngle)
Next
End Sub
//
Public Shared Function RotatePoint(ByVal pnt As PointF, ByVal origin As PointF, ByVal radAngle As Double) As PointF
Dim newPoint As New PointF()
Dim deltaX As Double = pnt.X - origin.X
Dim deltaY As Double = pnt.Y - origin.Y
newPoint.X = CSng((origin.X + (Math.Cos(radAngle) * deltaX - Math.Sin(radAngle) * deltaY)))
newPoint.Y = CSng((origin.Y + (Math.Sin(radAngle) * deltaX + Math.Cos(radAngle) * deltaY)))
Return newPoint
End Function
//
Public Shared Function GetBoundsF(ByVal pnts As PointF()) As RectangleF
Dim left As Single = pnts(0).X
Dim right As Single = pnts(0).X
Dim top As Single = pnts(0).Y
Dim bottom As Single = pnts(0).Y
For i As Integer = 1 To pnts.Length - 1
If pnts(i).X < left Then
left = pnts(i).X
ElseIf pnts(i).X > right Then
right = pnts(i).X
End If
If pnts(i).Y < top Then
top = pnts(i).Y
ElseIf pnts(i).Y > bottom Then
bottom = pnts(i).Y
End If
Next
Return New RectangleF(left, top, CSng(Math.Abs(right - left)), CSng(Math.Abs(bottom - top)))
End Function
Ma question est:
J'ai quelques BoundsAfterRotation qui ont été tournés d'un angle autour de son centre. Je change la largeur et/ou la hauteur des limites. Comment puis-je travailler en arrière pour trouver les images originales qui auraient créé le BoundsAfterRotation?
Je ne comprends pas votre question c'est une question purement mathématique AFAIK. Pouvez-vous reformuler votre question avec seulement du vocabulaire mathématique? Vous pouvez également consulter: http://en.wikipedia.org/wiki/Rotation_matrix – mathk
Connaissez-vous toujours l'angle? – Jens
@ mathk, C'est une question purement mathématique. Si j'ai un carré et le fais pivoter d'un angle puis augmente la largeur de W, je veux savoir combien la largeur et l'emplacement du carré original (pré-rotation) ont changé. Cela va, selon l'angle, être différent de W. – Jules