Frage

Ich habe ein Bild mit zwei Punkten, ausgerichtet etwas wie folgt aus:

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

Ich habe beide X, Y für beiden Punkte Koordinaten und ich brauche die Bild X Grad zu drehen, so dass es so aussieht, statt:

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

Im Grunde genommen, so dass sie ausgerichtet nebeneinander, was die Mathematik für das? (A Codebeispiel in C # wäre noch besser, aber nicht erforderlich)

War es hilfreich?

Lösung

Es kommt darauf an, welche Stelle Sie als „center“ verwenden möchten für Ihre Rotation. Lassen Sie uns den Punkt an die aufrufen und links pointA und die eine nach rechts und unten pointB. Wenn Sie möchten, um den Punkt A drehen, so dass Punkt B mit ihm ausgerichtet ist, in Radiant den Drehwinkel der Berechnung so gehen würde:

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

Ich weiß nicht, wie Sie Ihr Bild sind Handhabung, so dass die folgende gilt nur, wenn Sie System.Drawing.Graphics verwenden:

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

Hoffe, es hilft.

Andere Tipps

Kein Code, sorry, aber ein stratagy.

Sie müssen in der Lage, das Ergebnisbild zu erzeugen durch Abtasten des das Quellbildes. Sie kennen den Drehwinkel, so müssen Sie jetzt eine Mapper-Funktion, die auf das Original aus dem Ergebnis Karten erstellen zurück.

Der Code würde einfach jede Zeile des Ergebnisbildes scannen, und ordnen Sie die Pixel zurück in das Originalbild. Sie können eine einfache tun;

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

So, jetzt brauchen wir nur die magische „getOriginalPixel“ -Methode, und das ist, wo die Mathematik kommt.

Wenn wir das Bild um 0 Grad drehen, dann PlotX, ploty ist nur die X / Y des ursprünglichen Bildes. Aber das ist kein Spaß.

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

denke ich an das Quellpixel abbildet. Sie müssen überprüfen, ob es außerhalb der Grenzen ist und zurück nur schwarz oder etwas:)

Der Code unten funktioniert

  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;
        }
    }

Sie zuerst den Mittelpunkt finden:

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

Dann nutzen trigonomentry für den Winkel zu lösen. Ich gehe davon aus wir den Ursprung unserer zentralen Punkt indexiert haben, so habe ich jetzt eine neue X3 und Y3 zu einer der Punkte.

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

Wir sind für den unbekannten Winkel TH Lösung

Sin(TH) = opposite / hypotenuse

Also für TH lösen wir brauchen:

TH = Asin(y3 / hypotenuse)

Drehen von TH.

Siehe Wikipedia für trigonometrische Funktionen Referenz

Ausführen eine allgemeine 2D-Transformation beinhaltet ein Paar eqautions mit 6 Unbekannten zu lösen.

'x = xA + yB + C

'y = xD + Ge + D

Bei 3 entsprechende Punkte, haben Sie 6 knowns und das System gelöst werden kann. Sie haben nur 4 Punkte in diesem Fall, da Sie sich nicht um Scher egal, aber man könnte sich vorstellen, einen dritten Punkt bei 90 Grad auf der Linie durch die beiden anderen Punkte gebildet einzuführen. ein gedrehtes Bild Erstellen wird dann (pseudo codedily) nur so etwas wie:

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 );
  }
}

Wenn die Leistung wichtig ist, können die Multiplikationen in der inneren Schleife optimiert werden weg von der Feststellung, dass y * B nur Änderungen im äußeren Aussehen und dass NEWX, newy Änderung von Konstanten A und D in der inneren Schleife.

Sie müssen geometrische Drehmatrizen nachschlagen: dieser Website finden Sie eine detaillierte Erklärung

Doch für die besten Ergebnisse, müssen Sie vom Ziel zur Quelle zu transformieren und dann die Transformation für jedes Zielpixel verwenden:

m = rotation matrix

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

Es gibt in .NET Framework Methoden all dies zu tun: System.Drawing.Graphics.RotateTransform und System.Drawing.Graphics.TranslateTransform. Sie müssen eine Übersetzung einzurichten, um den Drehpunkt des Bildes auf den Ursprung zu bewegen, dann die Drehung anwenden und dann eine andere Übersetzung es in die Ausgangsposition zurückzukehren. Sie müssen mit diesen Funktionen experimentieren, herauszufinden, wie sie sich verhalten - ich bin im Moment bei der Arbeit und haben nicht die Zeit zur Hand einige Code zusammen zu bekommen, das funktioniert. : - (

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top