English 中文(简体)
How to distort a Sprite into a trapezoid?
原标题:

I am trying to transform a Sprite into a trapezoid, I don t really care about the interpolation even though I know without it my image will lose detail. All I really want to do is Transform my rectangular Sprite into a trapezoid like this:


  /        
 /         
/__________

Has anyone done this with CGAffineTransforms or with cocos2d?

最佳回答

The transformation you re proposing is not affine. Affine transformations have to be undoable. So they can typically:

  • Scale
  • Rotate
  • Shear (make lopsided, like square -> parallelogram)
  • Translate

But they cannot "squeeze". Notice that the left and right sides of your trapezoid, if extended, would intersect at a particular spot. They re not parallel anymore. So you couldn t "undo" the transformation, because if there was anything to transform at that spot, you couldn t decide where they would transform to. In other words, if a transformation doesn t preserve parallelism, it pinches space, can t be undone, and isn t affine.

I don t know that much about transformations in Core Animation, so I hope that mathy stuff helps you find an alternative.

But I do know how you could do it in OpenGL, but it would require you to start over on how you draw your application:

  1. If I m envisioning the result you want correctly, you want to build your rectangle in 3D, use an affine transformation to rotate it away a little bit, and use a (non-affine) projection transformation to flatten it into a 2D image.

  2. If you re not looking for a 3D effect, but you really just want to pinch in the corners, then you can specify a GL_RECT with the points of your trapezoid and map your sprite onto it as a texture.

The easiest thing might be to pre-squeeze your image in a photo editor, save it as a .png with transparency, and draw a rectangle with that image.

问题回答

You need to apply a CATransform3D to the layer of the UIView. To find out the right one, it is easier to use AGGeometryKit.

#import <AGGeometryKit/AGGeometryKit.h>

UIView *view = ...; // create a view

view.layer.anchorPoint = CGPointZero;
AGKQuad quad = view.layer.quadrilateral;
quad.tl.x += 20; // shift top left x-value with 20 pixels
quad.tr.x -= 20; // shift top right x-value with 20 pixels
view.layer.quadrilateral = quad; // the quad is converted to CATransform3D and applied




相关问题
List Contents of Directory in a UITableView

I am trying to list the contents of Ringtones directory in a TableView, however, I am only getting the last file in the directory in ALL cells, instead of file per cell. This is my code: - (...

iPhone NSUserDefaults persistance difficulty

In my app i have a bunch of data i store in the NSUserdefaults. This information consists of an NSObject (Object1) with NSStrings and NSNumbers and also 2 instances of yet another object (Object2). ...

Writing a masked image to disk as a PNG file

Basically I m downloading images off of a webserver and then caching them to the disk, but before I do so I want to mask them. I m using the masking code everyone seems to point at which can be found ...

Resize UIImage with aspect ratio?

I m using this code to resize an image on the iPhone: CGRect screenRect = CGRectMake(0, 0, 320.0, 480.0); UIGraphicsBeginImageContext(screenRect.size); [value drawInRect:screenRect blendMode:...

Allowing interaction with a UIView under another UIView

Is there a simple way of allowing interaction with a button in a UIView that lies under another UIView - where there are no actual objects from the top UIView on top of the button? For instance, ...

热门标签