Search code examples
objective-cios5trigonometryquartz-2dcgaffinetransform

Relationship Between Skew and Angle - CGAffineTransform


I am working on an iPad application that allows the user to draw a line with their finger, then using the beginning and end points of that line I calculate the angle of the line in relation to the x/y plane of the iPad.

My problem is that I want to use the angle of the drawn line to set the skew of an image that I am drawing into the current context.

This is the relavent code from my drawRect method:

         CGSize size =  CGSizeMake(1024, 768);
         UIGraphicsBeginImageContext(size);
         CGContextRef ctx = UIGraphicsGetCurrentContext();
         CGAffineTransform skewIt = CGAffineTransformMake(1, 0, skewValue, 1, 0, 0);
         CGContextConcatCTM(ctx, skewIt);

         CGContextDrawImage(UIGraphicsGetCurrentContext(),
                            CGRectMake(0,0,size.width, size.height),
                            theImage.CGImage);

        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();

I calculate the angle of the line in my touchEnded method, the point values of the drawn line are stored in an array named skewArray:

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    if (stepThree){
        CGContextClearRect(skewContext, CGRectMake(0, 0, 1024, 668));

        CGPoint pt1 = CGPointMake([[skewArray objectAtIndex:1]point3].x, [[skewArray objectAtIndex:1]point3].y);
        CGPoint pt2 = CGPointMake([[skewArray objectAtIndex:[skewArray count]-1]point3].x, [[skewArray objectAtIndex:[skewArray count]-1]point3].y);
        CGPoint pt3 = CGPointMake([[skewArray objectAtIndex:[skewArray count]-1]point3].x, [[skewArray objectAtIndex:1]point3].y);

        CGFloat dis1 = sqrt((pow((pt2.x - pt1.x), 2) + pow((pt2.y - pt1.y), 2)));
        CGFloat dis2 = sqrt((pow((pt3.x - pt2.x), 2) + pow((pt3.y - pt2.y), 2)));
        CGFloat dis3 = sqrt((pow((pt1.x - pt3.x), 2) + pow((pt1.y - pt3.y), 2)));

        angle = acos(((-1*pow(dis2, 2))+pow(dis1, 2)+pow(dis3, 2))/(2*dis1*dis3)) * 180/3.14;

        //Do something with the angle to produce the appropriate skew value

        [self setNeedsDisplay];
       }
   }

Thank you in advance for your help!


Solution

  • Check out this Wikipedia article on shear mapping. It looks like you'd be better off getting the slope and using 1.0 / m as you skew value.