Is it possible to use a normalized coordinate system (from 0.0 to 1.0) instead of using pixel coordinates when drawing stuff with CoreGraphics? It would certainly make a lot of things easier...
Yes, use a CGAffineTransform. I do this in an app. keep all coordinates normalized to -1.0 to 1.0, create a transform based on the size of the view I am drawing into.
Example:
CGAffineTransform translateTransform = CGAffineTransformMakeTranslation(offset.x, offset.y);
One can transform each point or create a path and transform the entire path:
CGMutablePathRef transformedPath = CGPathCreateMutable();
CGPathAddPath(transformedPath, &transform, path);
As #yurish points out one can also use CGContextScaleCTM, CGContextTranslateCTM, etc. instead of scaling the points/path if that works better for you.
Core graphics does not use pixel coordinates. It uses abstract points that are converted to pixels using current transformation matrix (CTM). You can use the normalized coordinate system if you adjust CTM appropriately (CGContextScaleCTM etc) .
Related
I have four points and I would like to draw an UIImageView with corners in those four points.
The four points represent an arbitrary rectangle (might be a trapez or a parallelogram).
I guess I somehow need to make a transform from those four points, but I'm not quite sure how.
Any suggestions?
Other solutions?
Look at https://math.stackexchange.com/questions/169176/2d-transformation-matrix-to-make-a-trapezoid-out-of-a-rectangle to determine your transformation matrix.
Note that you cannot use a 2D matrix so you have to use a CATransform3D.
CATransform3D transform = CATransform3DIdentity;
// update transform elements, .m11, .m12, .m13, etc.
imageView.layer.transform = transform;
There are:
1.
CGAffineTransform layerTransform = CGAffineTransformMakeRotation(M_PI_2);
layerTransform = CGAffineTransformTranslate(layerTransform, 1080, 0);
2.
CGAffineTransform layerTransform = CGAffineTransformMakeTranslation(1080, 0);
layerTransform = CGAffineTransformRotate(layerTransform, M_PI_2);
What's the different between them ?
Rotate before or after translate, is there any different?
CGAffineTransformTranslate is basically create a new affine transform by translating (moving) existing affine transform with specified method. We have to use CGAffineTransform CGAffineTransformTranslate ( CGAffineTransform t, CGFloat tx, CGFloat ty ) method for it. Here tx and ty has the values by which new affine transform have to move in X and Y direction respectively.
CGAffineTransformRotate is basically create a new affine transform by rotating existing transform with specified method. We have to use CGAffineTransform CGAffineTransformRotate ( CGAffineTransform t, CGFloat angle ) method for it. Here angle has the rotation angle for new affine transform.
I hope, you can get that first one is used to get a shift from one position to another one, and second one is used to get a roation.
The thing you need to know is that translation means move the location.
Rotation is self explanatory.
The order does matter depending on the origin point and the effect you want to achieve.
I'm Core Graphics this is lower left on a OS X and upper left on iOS.
In Core Animation objects can be transformed more easily by their center points.
CG works with rects though.
The most common hurtful thing is trying to rotate something about its center in CG.
If you just rotate transform the thing will appear to rotate around its origin like the hand of a clock.
So if you move the origin then rotate, you you can compensate for this.
The math is not easy unless you know trig and radians.
The trick is that you need to apply both transformations before drawing again or the thing will jump about.
Say I am using the below code to setup a projection view :
float aspect = fabsf(self.view.bounds.size.width / self.view.bounds.size.height);
GLKMatrix4 projectionMatrix = GLKMatrix4MakePerspective(GLKMathDegreesToRadians(65.0f), aspect, 4.0f, 10.0f);
self.effect.transform.projectionMatrix = projectionMatrix;
If I now wanted to make to camera look at a specific point in my scene, how would I best achieve this ? Currently I am changing the modelViewMatrix to move the object so it is centred in view, but am wondering if I could achieve the same by manipulating the projectionMatrix somehow.
As any good 3D programming basics tutorial (like maybe this one) will tell you...
A Model matrix converts vertex coordinates from model space (the coordinate space in which your mesh is specified, which is usually ignorant of where you want to place the model in the scene) to world space (the conceptual space of your scene).
A View matrix converts from world space to eye space (that is, a coordinate system relative to the "camera" that vies your scene).
A Projection matrix converts from eye space to clip space (a -1.0 to 1.0 cube representing your screen plus some depth, which the GPU then converts into pixel space).
The Projection matrix already works in terms relative to the viewpoint -- you've already fixed where the eye is and what point it's looking at, so the projection matrix only changes your field of view angle, aspect ratio, and near and far clipping planes. If you want to change the point you're looking at, specify a different LookAt transform for your View matrix.
I want to create the same transforming effect on XNA 4 as Photoshop does:
Transform tool is used to scale, rotate, skew, and just distort the perspective of any graphic you’re working with in general
This is what all the things i want to do in XNA with any textures http://www.tutorial9.net/tutorials/photoshop-tutorials/using-transform-in-photoshop/
Skew: Skew transformations slant objects either vertically or horizontally.
Distort: Distort transformations allow you to stretch an image in ANY direction freely.
Perspective: The Perspective transformation allows you to add perspective to an object.
Warping an Object(Im interesting the most).
Hope you can help me with some tutorial or somwthing already made :D, iam think vertex has the solution but maybe.
Thanks.
Probably the easiest way to do this in XNA is to pass a Matrix to SpriteBatch.Begin. This is the overload you want to use: MSDN (the transformMatrix argument).
You can also do this with raw vertices, with an effect like BasicEffect by setting its World matrix. Or by setting vertex positions manually, perhaps transforming them with Vector3.Transform().
Most of the transformation matrices you want are provided by the Matrix.Create*() methods (MSDN). For example, CreateScale and CreateRotationZ.
There is no provided method for creating a skew matrix. It should be something like this:
Matrix skew = Matrix.Identity;
skew.M12 = (float)Math.Tan(MathHelper.ToRadians(36.87f));
(That is to skew by 36.87f degrees, which I pulled off this old answer of mine. You should be able to find the full maths for a skew matrix via Google.)
Remember that transformations happen around the origin of world space (0,0). If you want to, for example, scale around the centre of your sprite, you need to translate that sprite's centre to the origin, apply a scale, and then translate it back again. You can combine matrix transforms by multiplying them. This example (untested) will scale a 200x200 image around its centre:
Matrix myMatrix = Matrix.CreateTranslation(-100, -100, 0)
* Matrix.CreateScale(2f, 0.5f, 1f)
* Matrix.CreateTranslation(100, 100, 0);
Note: avoid scaling the Z axis to 0, even in 2D.
For perspective there is CreatePerspective. This creates a projection matrix, which is a specific kind of matrix for projecting a 3D scene onto a 2D display, so it is better used with vertices when setting (for example) BasicEffect.Projection. In this case you're best off doing proper 3D rendering.
For distort, just use vertices and place them manually wherever you need them.
I am trying to understand quartz 2d coordinate system, Currently I am reading Apple reference guide and old book "Quartz 2d graphics for mac os x developer".
I understand the concept of user-space and device-space concept that device-space can have different default coordinate system and device-space coordinates can't be modified, and we map user-space by modifying its coordinate system acceding to device-space to achieve desire result.
First part of the problem
Quartz 2d graphics for mac os x developer book says:
When transforming a coordinate system, you must have another
coordinate system to compare it to. The transformation provides a
relative mapping from one coordinate system to the other. When you
draw in the transformed coordinate system, the transformation maps the
graphic back to the first coordinate system. The appearance of that
graphic in the fixed coordinate system is affected by the
transformation.
i didn't get this point in bold.
And
Quartz 2D programming guide says:
Quartz accomplishes device independence with a separate coordinate
system—user space—mapping it to the coordinate system of the output
device—device space—using the current transformation matrix, or CTM. A
matrix is a mathematical construct used to efficiently describe a set
of related equations. The current transformation matrix is a
particular type of matrix called an affine transform, which maps
points from one coordinate space to another by applying translation,
rotation, and scaling operations (calculations that move, rotate, and
resize a coordinate system).
The current transformation matrix has a secondary purpose: It allows
you to transform how objects are drawn. For example, to draw a box
rotated by 45 degrees, you rotate the coordinate system of the page
(the CTM) before you draw the box. Quartz draws to the output device
using the rotated coordinate system.
Confusion is that "Quartz draws to the output device using the rotated coordinate system.", if I want to draw one object(image etc) rotated and other with out rotation then what happen? We have whole coordinates rotated every thing will be drawn is rotated?
I am trying different experiments but unable to wrap my head around this, I create an image my drawing two line replicating bottom left coordinate system in photoshop and then added to my project to see visibly how coordinates are behaving by calling CGContextRotateCTM(myContext, 45); in drawrect method, but it didn't do any thing to image which I included in xib file using interface builder placing image inside uiimage.
this code is from quartz 2D programming guide
CGContextRef myContext = UIGraphicsGetCurrentContext();
CGRect contextRect = self.bounds;
CGContextTranslateCTM(myContext, 0, contextRect.size.height);
CGContextRotateCTM(myContext, 45); //my modification
CGContextScaleCTM(myContext, 1, -1);
float w, h;
w = contextRect.size.width;
h = contextRect.size.height;
CGAffineTransform myTextTransform;
CGContextSelectFont (myContext, "Helvetica-Bold", h/10, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (myContext, 10);
CGContextSetTextDrawingMode (myContext, kCGTextFillStroke);
CGContextSetRGBFillColor (myContext, 0, 1, 0, .5);
CGContextSetRGBStrokeColor (myContext, 0, 0, 1, 1);
myTextTransform = CGAffineTransformMakeRotation(0);
CGContextSetTextMatrix (myContext, myTextTransform);
CGContextShowTextAtPoint (myContext, 0, 50, "Quartz 2D", 9);
but this code is modifying the text drawn on screen not the image I added?
Second Part of the problem
This is also from Quartz 2D programming guide:
... apply a transform that translates the origin to the upper-left
corner of the PDF context and scales the y-coordinate by -1.
Using a scaling transform to negate the y-coordinate alters some
conventions in Quartz drawing. For example, if you call
CGContextDrawImage to draw an image into the context, the image is
modified by the transform when it is drawn into the destination. ...
I am already doing this -1 thing but no effect on image and this -1 thing is still not clear to me.
I have read this document several times, tried searching on google but no useful tutorial and also no latest books are available only books written in 2004, 2005, 2006. Can any one help regarding this or can refer me useful resources to learn this in depth.
Desperately waiting for replies, really need help.
Thank you.
Read this guide and I hope all your problems will be clear
https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CocoaDrawingGuide/Transforms/Transforms.html
Are you using a UIImageView subclass and overriding drawRect? This is not supported (see the docs) and is probably why your image is unaffected by any transformations.
If you want to do a lot of transformations and bespoke drawing code then you should be using a UIView subclass and drawing your image manually using CGContextDrawImage()
Any transforms are applied to drawing operations done after the transform. You will see code samples in the docs where the graphics state is saved, a transform applied, some drawing done, and then the context is restored. This is how you draw some components rotated and some not.
Hopefully the second part of your question will become clear once you are drawing your image via CG code and not via an image view.