visual una rotate rotar picture linea imagen girar figura como c# math image rotation

una - rotar linea c#



Girar imagen matemática(C#) (6)

Tengo una imagen con dos puntos, alineada de la siguiente manera:

|----------------| | | | . | | | | . | | | |----------------|

Tengo ambas coordenadas X, Y para ambos puntos y necesito rotar la imagen X grados para que se vea así:

|----------------| | | | | | . . | | | | | |----------------|

Básicamente para que se alineen uno al lado del otro, ¿cuál es la matemática de esto? (Un ejemplo de código en C # sería aún mejor, pero no obligatorio)


El siguiente código funciona

Matrix mRotate = new Matrix(); mRotate.Translate(Convert.ToInt32(Width.Value) / -2, Convert.ToInt32(Height.Value) / -2, MatrixOrder.Append); mRotate.RotateAt(theta, new Point(0, 0), MatrixOrder.Append); using (GraphicsPath gp = new GraphicsPath()) { // transform image points by rotation matrix gp.AddPolygon(new Point[] { new Point(0, 0), new Point(Convert.ToInt32(Width.Value), 0), new Point(0, Convert.ToInt32(Height.Value)) }); gp.Transform(mRotate); PointF[] pts = gp.PathPoints; // create destination bitmap sized to contain rotated source image Rectangle bbox = boundingBox(bmpSrc, mRotate); Bitmap bmpDest = new Bitmap(bbox.Width, bbox.Height); using (Graphics gDest = Graphics.FromImage(bmpDest)) { // draw source into dest Matrix mDest = new Matrix(); mDest.Translate(bmpDest.Width / 2, bmpDest.Height / 2, MatrixOrder.Append); gDest.Transform = mDest; gDest.DrawImage(bmpSrc, pts); gDest.DrawRectangle(Pens.Transparent, bbox); //drawAxes(gDest, Color.Red, 0, 0, 1, 100, ""); return bmpDest; } }


Depende del punto que desee usar como "centro" para su rotación. Llamemos el punto hacia arriba y el punto izquierdo A y el que está a la derecha y debajo del punto B. Si desea rotar alrededor del punto A para que el punto B se alinee con él, calcular el ángulo de rotación en radianes sería así:

double angle = Math.Atan2(pointB.Y - pointA.Y, pointB.X - pointA.X);

No sé cómo maneja su imagen, por lo que lo siguiente solo se aplica si está utilizando System.Drawing.Graphics:

myImage.TranslateTransform(-pointA.X, -pointA.Y); myImage.RotateTransform((float) angle, MatrixOrder.Append); myImage.TranslateTransform(pointA.X, pointA.Y, MatrixOrder.Append);

Espero eso ayude.


Primero encuentra el punto central:

Point p = new Point((x1-x2)/2, (y1-y2)/2)

Luego usa trigonometría para resolver el ángulo. Voy a suponer que hemos cambiado el origen de nuestro punto central, así que ahora tengo un nuevo x3 e y3 en uno de los puntos.

hypotenuse = SqrRt(x3^2 + y3^2)

Estamos resolviendo por el ángulo desconocido TH

Sin(TH) = opposite / hypotenuse

Entonces para resolver TH necesitamos:

TH = Asin(y3 / hypotenuse)

Girar por TH .

Ver Wikipedia para referencia de funciones trigonométricas


Realizar una transformación general en 2D implica resolver un par de ecuaciones con 6 incógnitas.

''x = xA + yB + C

''y = xD + yE + D

Teniendo en cuenta 3 puntos correspondientes, tendrá 6 conocimientos y el sistema se puede resolver. Solo tienes 4 puntos en este caso, ya que no te importa el corte, pero podrías imaginar introducir un tercer punto a 90 grados con respecto a la línea formada por los otros dos puntos. Crear una imagen girada es (pseudo codificado) algo así como:

for ( y = 0; y < height; y++ ) for ( x = 0; x < width; x++ ) { newx = x*A + y*B + C; newy = x*D + y*D + E; newimage(x,y ) = oldimage( newx, newy ); } }

Si el rendimiento es importante, las multiplicaciones en el bucle interno se pueden optimizar al notar que y * B solo cambia en el aspecto externo y que newx, newy cambia por las constantes A y D en el bucle interno.


Sin código, lo siento, pero es una estratagema.

Debe poder crear la imagen resultante al muestrear la imagen de origen. Ya conoce el ángulo de rotación, por lo que ahora necesita crear una función de correlacionador que redireccione desde el resultado al original.

El código simplemente escaneará cada fila de la imagen resultante y asignará el píxel a la imagen original. Puedes hacer un simple;

for (int plotY = 0; plotY < resultHeight; plotY++) { for (int plotX = 0; plotX < resultWidth; plotX++) { resultImage.PlotPixel(getOriginalPixel(plotX, plotY, angleOfRotation)); } }

Así que ahora solo necesitamos el método mágico "getOriginalPixel", y aquí es donde entra la matemática.

Si rotamos la imagen 0 grados, entonces plotX, plotY es solo la X / Y de la imagen original. Pero eso no es divertido.

pickX = x * cos(angle) - y * sin(angle) pickY = y * cos(angle) + x * sin(angle)

Creo que se asignará al píxel fuente. Tendrás que comprobar si está fuera de límites y solo devolver negro o algo :)


Necesita buscar matrices de rotación geométrica: consulte este sitio para obtener una explicación detallada

Sin embargo, para obtener los mejores resultados, debe transformarse del destino a la fuente y luego usar la transformación para cada píxel de destino:

m = rotation matrix for each point p in destination p'' = p.m get pixel p'' from source set pixle p in destination

Hay, en los métodos de .net framework para hacer todo esto: System.Drawing.Graphics.RotateTransform y System.Drawing.Graphics.TranslateTransform . Tendrá que configurar una traducción para mover el punto de rotación de la imagen al origen, luego aplicar la rotación y luego otra traducción para devolverla a la posición original. Necesitarás experimentar con estas funciones para descubrir cómo se comportan. Estoy trabajando en este momento y no tengo tiempo para obtener un código que funcione. :-(