Preserve Linienbreite, während alle Punkte im Zusammenhang mit CGAffineTransform Skalierung
-
22-09-2019 - |
Frage
habe ich ein CGPath
in einigem Koordinatensystem, dass ich ziehen möchte. Dabei beinhaltet das alte Koordinatensystem auf den eigenen Kontext Skalierung. Zu diesem Zweck verwende ich CGContextConcatCTM()
, welche die Punkte alle tun verwandeln, wie es sollte. Aber, da es eine Skalierungsoperation ist, erhalten die horizontale / vertikale Linienbreiten geändert. Z.B. eine Skala von 10 in x-Richtung, aber von 1 in Y-Richtung auf vertikale Linien so dick wie diejenigen horizontal sind 10mal führen würde. Gibt es eine Möglichkeit, die einfache Bedienung von Umsetzungsmatrizen zu halten (z CGAffineTransform
), aber nicht Linienbreiten bei gleichzeitig Skalierung, z.B. eine Funktion wie CGPathApplyAffineTransformToPoints
?
Prost
MrMage
Lösung
Sie können CGPathApply
iterieren durch die Elemente in einem Pfad verwenden. Es ist ein wenig komplexer als nur ein Einzeiler, aber wenn Sie es in einer einfachen Hilfsfunktion verpacken, könnte es für Sie nützlich sein. Hier ist eine Version, die einen neuen Weg und transformiert es schafft:
typedef struct {
CGMutablePathRef path;
CGAffineTransform transform;
} PathTransformInfo;
static void
PathTransformer(void *info, const CGPathElement *element)
{
PathTransformInfo *transformerInfo = info;
switch (element->type) {
case kCGPathElementMoveToPoint:
CGPathMoveToPoint(transformerInfo->path, &transformerInfo->transform,
element->points[0].x, element->points[0].y);
break;
case kCGPathElementAddLineToPoint:
CGPathAddLineToPoint(transformerInfo->path, &transformerInfo->transform,
element->points[0].x, element->points[0].y);
break;
case kCGPathElementAddQuadCurveToPoint:
CGPathAddQuadCurveToPoint(transformerInfo->path, &transformerInfo->transform,
element->points[0].x, element->points[0].y,
element->points[1].x, element->points[1].y);
break;
case kCGPathElementAddCurveToPoint:
CGPathAddCurveToPoint(transformerInfo->path, &transformerInfo->transform,
element->points[0].x, element->points[0].y,
element->points[1].x, element->points[1].y,
element->points[2].x, element->points[2].y);
break;
case kCGPathElementCloseSubpath:
CGPathCloseSubpath(transformerInfo->path);
break;
}
}
es nutzen zu können, tun würde (das ist der Teil I in einer Hilfsfunktion setzen würde):
PathTransformInfo info;
info.path = CGPathCreateMutable();
info.transform = CGAffineTransformMakeScale(2, 1);
CGPathApply(originalPath, &info, PathTransformer);
Der transformierte Pfad ist in info.path
an dieser Stelle.
Andere Tipps
Sie verwandeln das, wenn Sie den Pfad hinzufügen, aber dann die Transformation entfernen, bevor Sie Schlaganfall den Weg. Statt dessen:
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, 10, 10); // scale path 10x
CGContextAddPath(ctx, somePath);
CGContextSetStrokeColorWithColor(ctx, someColor);
CGContextSetLineWidth(ctx, someWidth); // uh-oh, line width is 10x, too
CGContextStrokePath(ctx);
CGContextRestoreGState(ctx); // back to normal
Tun Sie dies:
CGContextSaveGState(ctx);
CGContextScaleCTM(ctx, 10, 10); // scale path 10x
CGContextAddPath(ctx, somePath);
CGContextRestoreGState(ctx); // back to normal
CGContextSetStrokeColorWithColor(ctx, someColor);
CGContextSetLineWidth(ctx, someWidth);
CGContextStrokePath(ctx);