Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Çok yönlü dönüşüm matrisi ile SkiaSharp dönüşümlerine daha ayrıntılı bir şekilde göz at
Nesneye SKCanvas uygulanan tüm dönüşümler, yapının tek bir örneğinde SKMatrix birleştirilmiştir. Bu, tüm modern 2B grafik sistemlerindekine benzer standart bir 3'e 3 dönüşüm matrisidir.
Gördüğünüz gibi, dönüştürme matrisini bilmeden SkiaSharp'ta dönüşümleri kullanabilirsiniz, ancak dönüşüm matrisi teorik açıdan önemlidir ve yolları değiştirmek veya karmaşık dokunmatik girişi işlemek için dönüşümleri kullanırken ve her ikisi de bu makalede ve sonraki bölümde gösterilmiştir.

öğesine uygulanan SKCanvas geçerli dönüştürme matrisi, salt okunur TotalMatrix özelliğine erişerek istediğiniz zaman kullanılabilir. yöntemini kullanarak SetMatrix yeni bir dönüştürme matrisi ayarlayabilir ve çağırarak ResetMatrixbu dönüştürme matrisini varsayılan değerlere geri yükleyebilirsiniz.
Tuvalin matris dönüşümüyle doğrudan çalışan diğer SKCanvas tek üye, Concat iki matrisi birlikte çarparak birleştirir.
Varsayılan dönüştürme matrisi, kimlik matrisidir ve çapraz hücrelerde 1'lerden, diğer her yerde 0'lardan oluşur:
| 1 0 0 | | 0 1 0 | | 0 0 1 |
Statik SKMatrix.MakeIdentity yöntemi kullanarak bir kimlik matrisi oluşturabilirsiniz:
SKMatrix matrix = SKMatrix.MakeIdentity();
Varsayılan SKMatrix oluşturucu bir kimlik matrisi döndürmez. Tüm hücrelerin sıfır olarak ayarlandığı bir matris döndürür. Bu hücreleri el ile ayarlamayı planlamadığınız sürece oluşturucuyu kullanmayın SKMatrix .
SkiaSharp bir grafik nesnesi oluşturduğunda, her nokta (x, y) üçüncü sütunda 1 içeren 1'e 3 matrise etkili bir şekilde dönüştürülür:
| x y 1 |
Bu 1'e 3 matris, Z koordinatı 1 olarak ayarlanmış üç boyutlu bir noktayı temsil eder. İki boyutlu matris dönüştürmenin üç boyutta çalışmayı gerektirmesi için matematiksel nedenler (daha sonra açıklanacaktır) vardır. Bu 1'e 3 matrisi, 3B koordinat sistemindeki bir noktayı temsil ediyor olarak düşünebilirsiniz, ancak her zaman Z'nin 1'e eşit olduğu 2B düzlemde.
Bu 1'e 3 matris daha sonra dönüşüm matrisi ile çarpılır ve sonuç tuvalde işlenen noktadır:
| 1 0 0 |
| x y 1 | × | 0 1 0 | = | x' y' z' |
| 0 0 1 |
Standart matris çarpması kullanıldığında, dönüştürülen noktalar aşağıdaki gibidir:
x' = x
y' = y
z' = 1
Bu varsayılan dönüştürmedir.
Translate yöntemi nesnesinde SKCanvas çağrıldığında, tx yöntemin Translate ve ty bağımsız değişkenleri dönüştürme matrisinin üçüncü satırındaki ilk iki hücre olur:
| 1 0 0 | | 0 1 0 | | tx ty 1 |
Çarpma şu şekildedir:
| 1 0 0 |
| x y 1 | × | 0 1 0 | = | x' y' z' |
| tx ty 1 |
Dönüştürme formülleri şunlardır:
x' = x + tx
y' = y + ty
Ölçeklendirme faktörlerinin varsayılan değeri 1'dir. Yöntemini yeni SKCanvas bir nesnede çağırdığınızdaScale, sonuç dönüştürme matrisi köşegen hücrelerde ve sy bağımsız değişkenlerini içerirsx:
| sx 0 0 |
| x y 1 | × | 0 sy 0 | = | x' y' z' |
| 0 0 1 |
Dönüşüm formülleri aşağıdaki gibidir:
x' = sx · x
y' = sy · y
Çağrıdan Skew sonra dönüştürme matrisi, ölçeklendirme faktörlerine bitişik matris hücrelerinde iki bağımsız değişken içerir:
│ 1 ySkew 0 │
| x y 1 | × │ xSkew 1 0 │ = | x' y' z' |
│ 0 0 1 │
Dönüşüm formülleri şunlardır:
x' = x + xSkew · y
y' = ySkew · x + y
α açısı için veya RotateRadians çağrısı RotateDegrees için dönüştürme matrisi aşağıdaki gibidir:
│ cos(α) sin(α) 0 │
| x y 1 | × │ –sin(α) cos(α) 0 │ = | x' y' z' |
│ 0 0 1 │
Dönüştürme formülleri şunlardır:
x' = cos(α) · x - sin(α) · y
y' = sin(α) · x - cos(α) · y
α 0 derece olduğunda, kimlik matrisidir. α 180 derece olduğunda dönüştürme matrisi aşağıdaki gibidir:
| –1 0 0 | | 0 –1 0 | | 0 0 1 |
180 derece döndürme, bir nesneyi yatay ve dikey olarak çevirmeye eşdeğerdir ve bu, –1 ölçek faktörleri ayarlanarak da gerçekleştirilir.
Tüm bu dönüşüm türleri, benfin dönüşümleri olarak sınıflandırılır. Affine dönüşümleri hiçbir zaman matrisin 0, 0 ve 1 varsayılan değerlerinde kalan üçüncü sütununu içermez. Affine Olmayan Dönüşümler makalesinde, benfin olmayan dönüşümler ele alınmaktadır.
Matris Çarpımı
Dönüşüm matrisini kullanmanın önemli bir avantajı, bileşik dönüşümlerin genellikle SkiaSharp belgelerinde birleştirme olarak adlandırılan matris çarpmasıyla elde edilebilmesidir. içindeki SKCanvas dönüşümle ilgili yöntemlerin çoğu "önceden birleştirme" veya "pre-concat" ifadelerine başvurur. Bu, çarpma sırasını ifade eder. Bu, matris çarpmasının değişmez olmaması nedeniyle önemlidir.
Örneğin, yönteminin Translate belgelerinde "Geçerli matrisi belirtilen çeviriyle önceden bir arada kullanır" ifadesi yer alırken, yöntemin Scale belgelerinde "Geçerli matrisi belirtilen ölçekle önceden bir arada kullanır" ifadesi yer alır.
Bu, yöntem çağrısı tarafından belirtilen dönüşümün çarpan (sol işlenen) ve geçerli dönüşüm matrisinin multiplicand (sağ işlenen) olduğu anlamına gelir.
Bunun çağrılıp Translate ardından Scalegeldiğini varsayalım:
canvas.Translate(tx, ty);
canvas.Scale(sx, sy);
Dönüştürme Scale , bileşik dönüşüm matrisinin Translate dönüşümüyle çarpılır:
| sx 0 0 | | 1 0 0 | | sx 0 0 | | 0 sy 0 | × | 0 1 0 | = | 0 sy 0 | | 0 0 1 | | tx ty 1 | | tx ty 1 |
Scale daha önce Translate şu şekilde çağrılabilir:
canvas.Scale(sx, sy);
canvas.Translate(tx, ty);
Bu durumda çarpmanın sırası tersine çevrilir ve ölçeklendirme faktörleri çeviri faktörlerine etkili bir şekilde uygulanır:
| 1 0 0 | | sx 0 0 | | sx 0 0 | | 0 1 0 | × | 0 sy 0 | = | 0 sy 0 | | tx ty 1 | | 0 0 1 | | tx·sx ty·sy 1 |
Özet noktası olan yöntemi aşağıda bulabilirsiniz Scale :
canvas.Scale(sx, sy, px, py);
Bu, aşağıdaki çevirme ve ölçeklendirme çağrılarına eşdeğerdir:
canvas.Translate(px, py);
canvas.Scale(sx, sy);
canvas.Translate(–px, –py);
Üç dönüşüm matrisi, yöntemlerin kodda nasıl göründüğüne göre ters sırada çarpılır:
| 1 0 0 | | sx 0 0 | | 1 0 0 | | sx 0 0 | | 0 1 0 | × | 0 sy 0 | × | 0 1 0 | = | 0 sy 0 | | –px –py 1 | | 0 0 1 | | px py 1 | | px–px·sx py–py·sy 1 |
SKMatrix Yapısı
Yapısı, SKMatrix dönüştürme matrisinin dokuz hücresine karşılık gelen türün float dokuz okuma/yazma özelliğini tanımlar:
│ ScaleX SkewY Persp0 │ │ SkewX ScaleY Persp1 │ │ TransX TransY Persp2 │
SKMatrixayrıca türünde float[]adlı Values bir özelliği tanımlar. Bu özellik, , , , SkewYTransYPersp1SkewXTransXScaleYPersp0ve Persp2sırasıyla ScaleXtek bir çekimde dokuz değeri ayarlamak veya almak için kullanılabilir.
, ve hücreleri, Bağımsız Olmayan Dönüşümler makalesinde ele alınıyor.Persp2Persp1Persp0 Bu hücrelerin varsayılan değerleri 0, 0 ve 1 ise, dönüşüm aşağıdaki gibi bir koordinat noktasıyla çarpılır:
│ ScaleX SkewY 0 │
| x y 1 | × │ SkewX ScaleY 0 │ = | x' y' z' |
│ TransX TransY 1 │
x' = ScaleX · x + SkewX · y + TransX
y' = SkewX · x + ScaleY · y + TransY
z' = 1
Bu, tam iki boyutlu afin dönüşümüdür. Benfin dönüşümü paralel çizgileri korur, yani dikdörtgen hiçbir zaman paralelogram dışında bir şeye dönüştürülemez.
Yapısı, SKMatrix değer oluşturmak SKMatrix için birkaç statik yöntem tanımlar. Bu tüm dönüş SKMatrix değerleri:
MakeTranslationMakeScaleMakeScalebir özet noktasıylaMakeRotationradyan cinsinden açı içinMakeRotationpivot noktası olan radyan cinsinden açı içinMakeRotationDegreesMakeRotationDegreesbir özet noktasıylaMakeSkew
SKMatrix ayrıca, iki matrisi birleştirir ve bu da bunları çarpmak anlamına gelen birkaç statik yöntem tanımlar. Bu yöntemler , , PostConcatve olarak adlandırılır Concatve PreConcather birinin iki sürümü vardır. Bu yöntemlerin dönüş değeri yoktur; bunun yerine, var olan SKMatrix değerlere bağımsız değişkenler aracılığıyla ref başvururlar. Aşağıdaki örnekte, A, Bve R ("sonuç için") tüm SKMatrix değerlerdir.
İki Concat yöntem şöyle çağrılır:
SKMatrix.Concat(ref R, A, B);
SKMatrix.Concat(ref R, ref A, ref B);
Bunlar aşağıdaki çarpmayı gerçekleştirir:
R = B × A
Diğer yöntemlerin yalnızca iki parametresi vardır. İlk parametre değiştirilir ve yöntem çağrısından döndürülen iki matrisin çarpımını içerir. İki PostConcat yöntem şöyle çağrılır:
SKMatrix.PostConcat(ref A, B);
SKMatrix.PostConcat(ref A, ref B);
Bu çağrılar aşağıdaki işlemi gerçekleştirir:
A = A × B
İki PreConcat yöntem birbirine benzer:
SKMatrix.PreConcat(ref A, B);
SKMatrix.PreConcat(ref A, ref B);
Bu çağrılar aşağıdaki işlemi gerçekleştirir:
A = B × A
Bu yöntemlerin tüm ref bağımsız değişkenlere sahip sürümleri, temel alınan uygulamaları çağırmada biraz daha verimlidir, ancak kodunuzu okuyan ve bağımsız değişken içeren herhangi bir ref şeyin yöntemiyle değiştirildiğini varsayarsak, kafa karıştırıcı olabilir. Ayrıca, yöntemlerden birinin Make sonucu olan bir bağımsız değişkeni geçirmek genellikle kullanışlıdır, örneğin:
SKMatrix result;
SKMatrix.Concat(result, SKMatrix.MakeTranslation(100, 100),
SKMatrix.MakeScale(3, 3));
Bu, aşağıdaki matrisi oluşturur:
│ 3 0 0 │ │ 0 3 0 │ │ 100 100 1 │
Bu, çeviri dönüşümüyle çarpılan ölçek dönüşümüdür. Bu özel durumda, SKMatrix yapısı adlı SetScaleTranslatebir yöntem ile bir kısayol sağlar:
SKMatrix R = new SKMatrix();
R.SetScaleTranslate(3, 3, 100, 100);
Bu, oluşturucuyu kullanmanın güvenli olduğu birkaç durumdan SKMatrix biridir. yöntemi, SetScaleTranslate matrisin dokuz hücresinin tümünü ayarlar. Oluşturucuyu SKMatrix statik Rotate ve RotateDegrees yöntemlerle kullanmak da güvenlidir:
SKMatrix R = new SKMatrix();
SKMatrix.Rotate(ref R, radians);
SKMatrix.Rotate(ref R, radians, px, py);
SKMatrix.RotateDegrees(ref R, degrees);
SKMatrix.RotateDegrees(ref R, degrees, px, py);
Bu yöntemler, bir döndürme dönüşümünü var olan bir dönüşümle birleştirmez. Yöntemler matrisin tüm hücrelerini ayarlar. ve yöntemleriyle MakeRotationMakeRotationDegrees işlevsel olarak aynıdır, ancak değerin örneğini SKMatrix oluşturmaz.
Görüntülemek istediğiniz bir SKPath nesneniz olduğunu, ancak biraz farklı bir yönlendirmeye veya farklı bir merkez noktasına sahip olmasını tercih ettiğinizi varsayalım. yöntemini SKPath bağımsız SKMatrix değişkenle çağırarak Transform bu yolun tüm koordinatlarını değiştirebilirsiniz. Yol Dönüştürme sayfası bunun nasıl yapılacağını gösterir. PathTransform sınıfı bir alandaki nesneye HendecagramPath başvurur, ancak bu yola bir dönüşüm uygulamak için oluşturucusunu kullanır:
public class PathTransformPage : ContentPage
{
SKPath transformedPath = HendecagramArrayPage.HendecagramPath;
public PathTransformPage()
{
Title = "Path Transform";
SKCanvasView canvasView = new SKCanvasView();
canvasView.PaintSurface += OnCanvasViewPaintSurface;
Content = canvasView;
SKMatrix matrix = SKMatrix.MakeScale(3, 3);
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeRotationDegrees(360f / 22));
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(300, 300));
transformedPath.Transform(matrix);
}
...
}
Nesnenin HendecagramPath merkezi (0, 0) ve yıldızın 11 noktası bu merkezden dışarı doğru her yönde 100 birim genişletir. Bu, yolun hem pozitif hem de negatif koordinatları olduğu anlamına gelir. Yol Dönüştürme sayfası, bir yıldızla üç kat daha büyük ve tüm pozitif koordinatlarla çalışmayı tercih eder. Dahası, yıldızın bir noktasının doğrudan yukarı doğru işaret etmelerini istemiyor. Bunun yerine yıldızın bir noktasının aşağı doğru işaret etmelerini istiyor. (Yıldızın 11 puanı olduğundan ikisini birden içeremez.) Bunun için yıldızın 360 derece 22'ye bölünmesi gerekir.
Oluşturucu aşağıdaki desene sahip yöntemini kullanarak PostConcat üç ayrı dönüşümden bir SKMatrix nesne oluşturur; burada A, B ve C örnekleridirSKMatrix:
SKMatrix matrix = A;
SKMatrix.PostConcat(ref A, B);
SKMatrix.PostConcat(ref A, C);
Bu bir dizi ardışık çarpmadır, bu nedenle sonuç aşağıdaki gibidir:
A × B × C
Ardışık çarpmalar, her dönüşümün ne yaptığını anlamaya yardımcı olur. Ölçek dönüşümü, yol koordinatlarının boyutunu 3 kat artırır, dolayısıyla koordinatlar –300 ile 300 arasında değişir. Döndürme dönüşümü, yıldızı kaynağı çevresinde döndürür. Çeviri dönüştürmesi daha sonra 300 piksel sağa ve aşağı kaydırır, böylece tüm koordinatlar pozitif olur.
Aynı matrisi üreten başka diziler de vardır. İşte bir tane daha:
SKMatrix matrix = SKMatrix.MakeRotationDegrees(360f / 22);
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeTranslation(100, 100));
SKMatrix.PostConcat(ref matrix, SKMatrix.MakeScale(3, 3));
Bu, yolu önce merkezi çevresinde döndürür ve ardından 100 piksel sağa ve aşağı doğru çevirerek tüm koordinatların pozitif olmasını sağlar. Yıldız daha sonra nokta olan yeni sol üst köşesine göre (0, 0) büyütülür.
İşleyici PaintSurface yalnızca şu yolu işleyebilir:
public class PathTransformPage : ContentPage
{
...
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
using (SKPaint paint = new SKPaint())
{
paint.Style = SKPaintStyle.Stroke;
paint.Color = SKColors.Magenta;
paint.StrokeWidth = 5;
canvas.DrawPath(transformedPath, paint);
}
}
}
Tuvalin sol üst köşesinde görünür:
Bu programın oluşturucusunun matrisi yola aşağıdaki çağrıyla uygular:
transformedPath.Transform(matrix);
Yol bu matrisi bir özellik olarak tutmaz. Bunun yerine, dönüşümü yolun tüm koordinatlarına uygular. Yeniden çağrılırsa Transform dönüşüm yeniden uygulanır ve geri dönmenin tek yolu dönüşümü geri alan başka bir matris uygulamaktır. Neyse ki yapı, SKMatrix belirli bir TryInvert matrisi tersine çeviren matrisi alan bir yöntem tanımlar:
SKMatrix inverse;
bool success = matrix.TryInverse(out inverse);
Yöntem çağrılır TryInverse çünkü tüm matrisler ters çevrilemez değildir, ancak grafik dönüşümü için ters çevrilemez bir matris kullanılma olasılığı düşüktür.
Ayrıca bir değere, bir nokta dizisine SKPoint , bir SKRectveya hatta programınızdaki tek bir sayıya matris dönüşümü uygulayabilirsiniz. yapısı SKMatrix , bu işlemleri aşağıdakiler gibi sözcüğüyle Mapbaşlayan bir yöntem koleksiyonuyla destekler:
SKPoint transformedPoint = matrix.MapPoint(point);
SKPoint transformedPoint = matrix.MapPoint(x, y);
SKPoint[] transformedPoints = matrix.MapPoints(pointArray);
float transformedValue = matrix.MapRadius(floatValue);
SKRect transformedRect = matrix.MapRect(rect);
Bu son yöntemi kullanırsanız, yapının döndürülmüş dikdörtgeni temsil edebildiğini unutmayın SKRect . yöntemi yalnızca çeviriyi ve ölçeklendirmeyi temsil eden bir SKMatrix değer için mantıklıdır.
Etkileşimli Deneme
Eşlem dönüşümünü hissetmenin bir yolu, bit eşleminin üç köşesini etkileşimli olarak ekranda hareket ettirmek ve hangi dönüşüm sonuçlarının dönüştürüldüğünü görmektir. Bu, Affine Matrisini Göster sayfasının arkasındaki fikirdir . Bu sayfa, diğer tanıtımlarda da kullanılan iki sınıf daha gerektirir:
sınıfı, TouchPoint ekranda sürüklenebilen yarı saydam bir daire görüntüler. TouchPoint bir öğesinin SKCanvasView üst öğesi olan veya öğesinin SKCanvasView ekli olmasını TouchEffect gerektirir. Capture özelliğini true olarak ayarlayın. Olay işleyicisindeTouchAction, programın her TouchPoint örnek için içinde yöntemini TouchPoint çağırması ProcessTouchEvent gerekir. Yöntem, dokunma olayının dokunma noktasının hareketle sonuçlandığı durumlarda döndürür true . Ayrıca işleyicinin PaintSurface her TouchPoint örnekte yöntemini çağırıp Paint nesnesine geçirmesi SKCanvas gerekir.
TouchPoint Bir SkiaSharp görselin ayrı bir sınıfta kapsüllenmek için yaygın bir yol gösterir. sınıfı görselin özelliklerini belirtmek için özellikler tanımlayabilir ve bağımsız değişkenle adlı Paint bir SKCanvas yöntem bunu işleyebilir.
Center özelliği TouchPoint nesnenin konumunu gösterir. Bu özellik konumu başlatacak şekilde ayarlanabilir; özelliği, kullanıcı daireyi tuvalin çevresinde sürüklediğinde değişir.
Giriş Matrisini Göster Sayfası da sınıfı gerektirir MatrixDisplay . Bu sınıf bir SKMatrix nesnenin hücrelerini görüntüler. İki genel yöntemi vardır: Measure işlenen matrisin boyutlarını elde etmek ve Paint görüntülemek için. sınıfı, farklı bir MatrixPaint yazı tipi boyutu veya rengi için değiştirilebilen türde SKPaint bir özellik içerir.
ShowAffineMatrixPage.xaml dosyası örneği oluşturur SKCanvasView ve bir TouchEffectekler. Arka planda kod ShowAffineMatrixPage.xaml.cs dosyası üç TouchPoint nesne oluşturur ve bunları ekli bir kaynaktan yükleyebilen bit eşlemin üç köşesine karşılık gelen konumlara ayarlar:
public partial class ShowAffineMatrixPage : ContentPage
{
SKMatrix matrix;
SKBitmap bitmap;
SKSize bitmapSize;
TouchPoint[] touchPoints = new TouchPoint[3];
MatrixDisplay matrixDisplay = new MatrixDisplay();
public ShowAffineMatrixPage()
{
InitializeComponent();
string resourceID = "SkiaSharpFormsDemos.Media.SeatedMonkey.jpg";
Assembly assembly = GetType().GetTypeInfo().Assembly;
using (Stream stream = assembly.GetManifestResourceStream(resourceID))
{
bitmap = SKBitmap.Decode(stream);
}
touchPoints[0] = new TouchPoint(100, 100); // upper-left corner
touchPoints[1] = new TouchPoint(bitmap.Width + 100, 100); // upper-right corner
touchPoints[2] = new TouchPoint(100, bitmap.Height + 100); // lower-left corner
bitmapSize = new SKSize(bitmap.Width, bitmap.Height);
matrix = ComputeMatrix(bitmapSize, touchPoints[0].Center,
touchPoints[1].Center,
touchPoints[2].Center);
}
...
}
Bir benfin matrisi üç noktayla benzersiz olarak tanımlanır. Üç TouchPoint nesne bit eşleminin sol üst, sağ üst ve sol alt köşelerine karşılık gelir. Bir benfin matrisi yalnızca dikdörtgeni paralelograma dönüştürebildiğinden, dördüncü nokta diğer üçü tarafından örtülür. Oluşturucu, bu üç noktadan bir SKMatrix nesnenin hücrelerini hesaplayan öğesine yapılan bir çağrıyla ComputeMatrixson bulur.
İşleyici, TouchAction her TouchPointöğesinin ProcessTouchEvent yöntemini çağırır. Değer scale koordinatlardan Xamarin.Forms piksellere dönüştürülür:
public partial class ShowAffineMatrixPage : ContentPage
{
...
void OnTouchEffectAction(object sender, TouchActionEventArgs args)
{
bool touchPointMoved = false;
foreach (TouchPoint touchPoint in touchPoints)
{
float scale = canvasView.CanvasSize.Width / (float)canvasView.Width;
SKPoint point = new SKPoint(scale * (float)args.Location.X,
scale * (float)args.Location.Y);
touchPointMoved |= touchPoint.ProcessTouchEvent(args.Id, args.Type, point);
}
if (touchPointMoved)
{
matrix = ComputeMatrix(bitmapSize, touchPoints[0].Center,
touchPoints[1].Center,
touchPoints[2].Center);
canvasView.InvalidateSurface();
}
}
...
}
Herhangi biri TouchPoint taşınmışsa yöntemi yeniden çağırır ComputeMatrix ve yüzeyi geçersiz kılabilir.
yöntemi, ComputeMatrix bu üç nokta tarafından ima edilen matrisi belirler. adlı A matris, bir piksel kare dikdörtgeni üç noktayı temel alan bir paralelograma dönüştürürken, adlı S ölçek dönüşümü bit eşlemi bir piksel kare dikdörtgene ölçeklendirir. Bileşik matris ×A:S
public partial class ShowAffineMatrixPage : ContentPage
{
...
static SKMatrix ComputeMatrix(SKSize size, SKPoint ptUL, SKPoint ptUR, SKPoint ptLL)
{
// Scale transform
SKMatrix S = SKMatrix.MakeScale(1 / size.Width, 1 / size.Height);
// Affine transform
SKMatrix A = new SKMatrix
{
ScaleX = ptUR.X - ptUL.X,
SkewY = ptUR.Y - ptUL.Y,
SkewX = ptLL.X - ptUL.X,
ScaleY = ptLL.Y - ptUL.Y,
TransX = ptUL.X,
TransY = ptUL.Y,
Persp2 = 1
};
SKMatrix result = SKMatrix.MakeIdentity();
SKMatrix.Concat(ref result, A, S);
return result;
}
...
}
Son olarak yöntemi bit PaintSurface eşlemi bu matrise göre işler, ekranın en altında matrisi görüntüler ve bit eşlemin üç köşesindeki dokunma noktalarını işler:
public partial class ShowAffineMatrixPage : ContentPage
{
...
void OnCanvasViewPaintSurface(object sender, SKPaintSurfaceEventArgs args)
{
SKImageInfo info = args.Info;
SKSurface surface = args.Surface;
SKCanvas canvas = surface.Canvas;
canvas.Clear();
// Display the bitmap using the matrix
canvas.Save();
canvas.SetMatrix(matrix);
canvas.DrawBitmap(bitmap, 0, 0);
canvas.Restore();
// Display the matrix in the lower-right corner
SKSize matrixSize = matrixDisplay.Measure(matrix);
matrixDisplay.Paint(canvas, matrix,
new SKPoint(info.Width - matrixSize.Width,
info.Height - matrixSize.Height));
// Display the touchpoints
foreach (TouchPoint touchPoint in touchPoints)
{
touchPoint.Paint(canvas);
}
}
}
Aşağıdaki iOS ekranı, sayfa ilk kez yüklendiğinde bit eşlemi gösterirken, diğer iki ekran bunu bazı düzenlemelerden sonra gösterir:
Dokunma noktaları bit eşlem köşelerini sürükler gibi görünse de, bu sadece bir yanılsamadır. Dokunma noktalarından hesaplanan matris bit eşlemi dönüştürerek köşelerin dokunma noktalarıyla çakışmasını sağlar.
Kullanıcıların bit eşlemleri köşeleri sürükleyerek değil, sürüklemek, sıkıştırmak ve döndürmek için doğrudan nesnenin üzerinde bir veya iki parmağı kullanarak taşıması, yeniden boyutlandırması ve döndürmesi daha doğaldır. Bu, bir sonraki Dokunma Manipülasyonu makalesinde ele alınmıştır.
3'e 3 Matrisin Nedeni
İki boyutlu bir grafik sisteminin yalnızca 2'ye 2 dönüştürme matrisi gerektirmesi beklenebilir:
│ ScaleX SkewY │
| x y | × │ │ = | x' y' |
│ SkewX ScaleY │
Bu ölçeklendirme, döndürme ve hatta eğme için çalışır, ancak çeviri olan en temel dönüşümleri gerçekleştiremeyebilir.
Sorun, 2'ye 2 matrisin iki boyutta doğrusal bir dönüşümü temsil ediyor olmasıdır. Doğrusal dönüşüm bazı temel aritmetik işlemleri korur, ancak bunun etkilerinden biri doğrusal dönüşümün noktayı hiçbir zaman değiştirmemesidir (0, 0). Doğrusal dönüşüm çeviriyi imkansız hale getirir.
Üç boyutta doğrusal dönüşüm matrisi şöyle görünür:
│ ScaleX SkewYX SkewZX │
| x y z | × │ SkewXY ScaleY SkewZY │ = | x' y' z' |
│ SkewXZ SkewYZ ScaleZ │
Etiketli SkewXY hücre, değerin Y değerlerine göre X koordinatını çarpıttığını, hücre SkewXZ ise değerin Z değerlerine göre X koordinatını çarpıttığını, diğer Skew hücreler için de değerlerin benzer şekilde çarpıtıldığını gösterir.
Bu 3B dönüştürme matrisi, 0 ScaleZ ve SkewZY 1 olarak ayarlanarak SkewZX iki boyutlu bir düzlemle kısıtlayabilirsiniz:
│ ScaleX SkewYX 0 │
| x y z | × │ SkewXY ScaleY 0 │ = | x' y' z' |
│ SkewXZ SkewYZ 1 │
İki boyutlu grafikler, Z'nin 1'e eşit olduğu 3B alanda düzleme tamamen çizilirse, dönüşüm çarpması şu şekilde görünür:
│ ScaleX SkewYX 0 │
| x y 1 | × │ SkewXY ScaleY 0 │ = | x' y' 1 |
│ SkewXZ SkewYZ 1 │
Her şey, Z'nin 1'e eşit olduğu iki boyutlu düzlemde kalır, ancak SkewXZ ve SkewYZ hücreleri etkili bir şekilde iki boyutlu çeviri faktörleri haline gelir.
Bu, üç boyutlu doğrusal dönüşümün iki boyutlu doğrusal olmayan bir dönüşüm görevi görür. (Benzetmeyle, 3B grafiklerdeki dönüşümler 4'e 4 matrisi temel alır.)
SKMatrix SkiaSharp içindeki yapı, bu üçüncü satırın özelliklerini tanımlar:
│ ScaleX SkewY Persp0 │
| x y 1 | × │ SkewX ScaleY Persp1 │ = | x' y' z` |
│ TransX TransY Persp2 │
sıfır olmayan ve değerleri, nesneleri Z'nin Persp0Persp1 1'e eşit olduğu iki boyutlu düzlemden hareket ettiren dönüşümlerle sonuçlanır. Bu nesneler o düzleme geri taşındığında ne olacağı Affine Dışı Dönüşümler makalesinde ele alınmıştır.

