ios - traslacion - transformaciones matematicas
Transformación afín de un paso para la rotación alrededor de un punto? (4)
¿Cómo puedo hacer una transformación afín Core Graphics para la rotación alrededor de un punto x, y de ángulo a, usando solo una llamada a CGAffineTransformMake () más funciones math.h trig como sin (), cos (), etc. y no hay otras llamadas CG.
Otras respuestas aquí parecen ser sobre el uso de múltiples transformadas apiladas o transformaciones de varios pasos para mover, rotar y mover, usando múltiples llamadas de gráficos principales. Esas respuestas no cumplen mis requisitos específicos.
Echa un vistazo a este enlace: Girar una vista de iPhone alrededor de un punto . Puede ser de ayuda. Hacia la parte inferior del artículo, hay una sección titulada "Cambiar el punto de anclaje". Esto es probablemente lo más adecuado para sus necesidades, aunque se debe hacer alguna compensación para no compensar la vista.
Para aquellos como yo, que están luchando en la búsqueda de una solución completa para rotar una imagen y escalarla adecuadamente, para llenar el marco contenedor, después de un par de horas, esta es la solución más completa e impecable que he obtenido.
El truco aquí es traducir el punto de referencia, antes de cualquier trasformación involucrada (tanto la escala como la rotación). Después de eso, debes concatenar las dos transformaciones para obtener una transformación afín completa.
He empacado la solución completa en una subclase de CIFilter que puedes leer aquí .
Siguiendo la parte relevante del código:
CGFloat a = _inputDegree.floatValue;
CGFloat x = _inputImage.extent.size.width/2.0;
CGFloat y = _inputImage.extent.size.height/2.0;
CGFloat scale = [self calculateScaleForAngle:GLKMathRadiansToDegrees(a)];
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);
CGAffineTransform transform2 = CGAffineTransformMakeTranslation(x, y);
transform2 = CGAffineTransformScale(transform2, scale, scale);
transform2 = CGAffineTransformTranslate(transform2,-x,-y);
CGAffineTransform concate = CGAffineTransformConcat(transform2, transform);
Una rotación de ángulo a alrededor del punto (x, y) corresponde a la transformación afín:
CGAffineTransform transform = CGAffineTransformMake(cos(a),sin(a),-sin(a),cos(a),x-x*cos(a)+y*sin(a),y-x*sin(a)-y*cos(a));
Es posible que necesite enchufar -a en lugar de a dependiendo de si desea que la rotación sea en sentido horario o antihorario. Además, es posible que deba enchufar -y en lugar de y- dependiendo de si su sistema de coordenadas está o no al revés.
Además, puedes lograr exactamente lo mismo en tres líneas de código usando:
CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);
Si estaba aplicando esto a una vista, también podría simplemente usar una transformación de rotación a través de CGAffineTransformMakeRotation (a), siempre que establezca la propiedad anchorPoint de la capa de la vista para reflejar el punto que desea rotar. Sin embargo, parece que no está interesado en aplicar esto a una vista.
Finalmente, si aplica esto a un espacio 2D no euclidiano, es posible que no desee una transformación afín. Las transformaciones afines son isometrías del espacio euclidiano, lo que significa que conservan la distancia euclidiana estándar, así como los ángulos. Si su espacio no es euclidiano, entonces la transformación que desea puede no ser afín, o si es afín, la matriz para la rotación puede no ser tan simple como lo que escribí arriba con sin y cos. Por ejemplo, si estuvieras en un espacio hiperbólico, podrías necesitar usar las funciones trigonométricas hiperbólicas sinh y cosh, junto con diferentes signos + y - en la fórmula.
PD: También quería recordarle a cualquiera que haya leído hasta aquí que "afín" se pronuncia con una "a" breve como en "preguntar", no una "a" larga como en "capaz". Incluso he escuchado a los empleados de Apple pronunciarlo mal en sus conversaciones de WWDC.
Use la capa de la vista y el punto de anclaje. p.ej
view.layer.anchorPoint = CGPoint(x:0,y:1.0)