Я пытаюсь написать матричное преобразование для преобразования точек диаграммы в пиксели устройства в SkiaSharp. У меня это работает, пока я использую 0,0 как минимальные координаты графика, но если мне нужно подняться с отрицательного числа, это заставит рисунок сместиться влево и вниз. То есть ось X смещена влево за пределы окна, а ось Y смещена за пределы окна.
Это предназначено для типичного линейного графика (минимальная точка на графике внизу слева) в то время как минимальная точка устройства в левом верхнем углу). Я учел это уже в преобразовании.
Проходя по коду, я вижу, что координаты, возвращаемые из матрицы, не те, которые я ожидал, поэтому я считаю, что проблема связана с моим преобразованием, но Я не смог точно определить это.
ОБНОВЛЕНИЕ: После дальнейшего изучения, я считаю, что я ошибся, он не сдвинут, он просто не масштабируется должным образом до максимального конца экран. В верхней и правой части графика больше поля, чем должно быть, но с нижней и левой стороны все в порядке. Мне не удалось определить, почему масштабирование не заполняет холст.
Ниже приведены мои матричные методы:
private SKMatrix ChartToDeviceMatrix, DeviceToChartMatrix;
private void ConfigureTransforms(SKPoint ChartMin,
SKPoint ChartMax, SKPoint DeviceMin, SKPoint DeviceMax)
{
this.ChartToDeviceMatrix = SKMatrix.MakeIdentity();
float xScale = (DeviceMax.X - DeviceMin.X) / (ChartMax.X - ChartMin.X);
float yScale = (DeviceMin.Y - DeviceMax.Y) / (ChartMax.Y - ChartMin.Y);
this.ChartToDeviceMatrix.SetScaleTranslate(xScale, yScale, DeviceMin.X, DeviceMax.Y);
this.ChartToDeviceMatrix.TryInvert(out this.DeviceToChartMatrix);
}
// Transform a point from chart to device coordinates.
private SKPoint ChartToDevice(SKPoint point)
{
return this.ChartToDeviceMatrix.MapPoint(point);
}
Код, вызывающий это:
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
float strokeWidth = 1;
float margin = 10;
// SKPaint definitions omitted for brevity.
var ChartMin = new SKPoint(-10, -1); // Works fine if I change this to 0,0
var ChartMax = new SKPoint(110, 11);
var DeviceMin = new SKPoint(margin, margin);
var DeviceMax = new SKPoint(info.Width - margin, info.Height - margin);
const float stepX = 10;
const float stepY = 1;
const float tickX = 0.5;
const float tickY = 0.075F;
// Prepare the transformation matrices.
this.ConfigureTransforms(ChartMin, ChartMax, DeviceMin, DeviceMax);
// Draw the X axis.
var lineStart = new SKPoint(ChartMin.X, 0);
var lineEnd = new SKPoint(ChartMax.X, 0);
canvas.DrawLine(this.ChartToDevice(lineStart), this.ChartToDevice(lineEnd), axisPaint);
// X Axis Tick Marks
for (float x = stepX; x <= ChartMax.X - stepX; x += stepX)
{
var tickMin = new SKPoint(x, -tickY);
var tickMax = new SKPoint(x, tickY);
canvas.DrawLine(this.ChartToDevice(tickMin), this.ChartToDevice(tickMax), axisPaint);
}
// Draw the Y axis.
// The inversion of above, basically the same.