0

I am trying to draw a affine rectangle (with rotation and skew) on top of an image but don't know how to calculate the vertices. I don't have a background in maths or matrix operations.

My affine class is defined as follows:

public class AffineRectangle
{
public double X { get; set; }
public double Y { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Rotation { get; set; }
public double Skew { get; set; }
}

I plan on using the ImageSharp library to draw a polygon using code similar to this:

using (Image<Rgba32> image = new Image<Rgba32>(800, 800))
{
  image.Mutate(x => x.DrawPolygon(
      Rgba32.Red,
      10,
      new SixLabors.Primitives.PointF[] {
          new Vector2(10, 10),
          new Vector2(550, 50),
          etc...
      }));
  image.Save("test.bmp");
}

Edit: it's a dotnet core Web service that I'm writing.

canice
  • 363
  • 1
  • 4
  • 16

2 Answers2

1

Any combination of of linear transformations can be combined into a single matrix and applied all at once. In the System.Windows.Media namespace there are some classes you can use to do the math for you. You'll need a reference to PresentationCore.dll, which you may already have if you're writing a WPF application.

Example:

using System.Windows.Media;

var myPoint = new Point(10, 10);
var transforms = new TransformGroup();
transforms.Children.Add(new RotateTransform(90));
transforms.Children.Add(new SkewTransform(0, 30));
var transformedPoint = transforms.Transform(myPoint);

EDIT: For projects targeting .NET Core, you can reference the System.Drawing.Common package to achieve similar functionality. Example code below:

using System.Drawing;
using System.Drawing.Drawing2D;

var myPoint = new PointF(10, 10);
var transform = new Matrix();
transform.Rotate(90.0f);
transform.Shear(5, 0);
var transformed = new PointF[] { myPoint };
transform.TransformPoints(transformed);
RogerN
  • 3,761
  • 11
  • 18
1

Current API (beta6) would be something like this.

using (var image = new Image<Rgba32>(800, 800))
{
    var builder = new AffineTransformBuilder()
            .AppendSkewDegrees(10F, 5F)
            .AppendRotationDegrees(45F);

    var rectangle = new Rectangle(0, 0, 150, 150);
    var polygon = new RectangularPolygon(rectangle);
    Matrix3x2 matrix = builder.BuildMatrix(rectangle);

    image.Mutate(x => x.Draw(
        Rgba32.Red,
        10,
        polygon.Transform(matrix)));

    image.Save("test.bmp");
}
James South
  • 10,147
  • 4
  • 59
  • 115