Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

skew UIView without giving perspective and keeping heigh and width

Skew Example Hi,

I am trying to achieve a transformation like in the image but I only have got a similar transformation but with perspective (which I don't want) using CGATransform3D. How could I achieve this using objective-c? The transformed image should have the same heigh and width than the original but with the base tilted by a given angle.

Thanks in advance for your help.

like image 897
user2248891 Avatar asked Mar 02 '16 21:03

user2248891


Video Answer


1 Answers

This is a “shear” or “skew” transformation. Luckily for you, shear transformations are affine transformations, and iOS supports affine transformations at both the UIView and CALayer levels. However, it has no convenience functions to construct shear transforms, so let's write one:

static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
    return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}

It's not obvious exactly what xShear and yShear mean. xShear is the tangent of the angle by which the y-axis is skewed, and yShear is the tangent of the angle by which the x-axis is skewed. This may seem backwards, but it has the visual effect you expect: a non-zero xShear tilts the figure left or right, and a non-zero yShear tilts the figure up or down.

Since tan π/4 = 1 (or, if you prefer, tan 45° = 1), the transform returned by affineTransformMakeShear(1, 0) turns a rectangle into a parallelogram whose left and right edges are at π/4 radians (or 45°).

Demo:

shear demo

Note that shearing on both axes can be identical to the combination of a rotation and a scale.

Here's my demo code:

#import "ViewController.h"

@interface ViewController ()

@property (strong, nonatomic) IBOutlet UIView *shearedView;
@property (strong, nonatomic) IBOutlet UISlider *verticalShearSlider;
@property (strong, nonatomic) IBOutlet UISlider *horizontalShearSlider;
@property (strong, nonatomic) IBOutlet UILabel *verticalShearLabel;
@property (strong, nonatomic) IBOutlet UILabel *horizontalShearLabel;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    [self updateAppearance:nil];
}

static CGAffineTransform affineTransformMakeShear(CGFloat xShear, CGFloat yShear) {
    return CGAffineTransformMake(1, yShear, xShear, 1, 0, 0);
}

- (IBAction)updateAppearance:(id)sender {
    CGFloat xShear = self.horizontalShearSlider.value;
    CGFloat yShear = self.verticalShearSlider.value;
    self.shearedView.transform = affineTransformMakeShear(xShear, yShear);
    self.horizontalShearLabel.text = [NSString stringWithFormat:@"%.2f", xShear];
    self.verticalShearLabel.text = [NSString stringWithFormat:@"%.2f", yShear];
}

@end
like image 154
rob mayoff Avatar answered Oct 04 '22 02:10

rob mayoff