Why did Apple flip their unit circle for UIBezierPath? - ios

The image on the left is what a typical unit circle looks like. The one on the right is from the documentation. I haven't seen a more in depth explanation for why it was flipped anywhere online. Why is this so?

A drawing of a circle is often represented by x = center.x + r * cos(φ) and y = center.y + r * sin(φ) as φ progresses from 0 to 2π. With a standard Cartesian coordinate system, with the origin in the lower-left corner, this results in a circle drawn, starting at 3 o'clock and proceeding counterclockwise. See diagram to the left, below.
But the iOS coordinate system has the the y-axis flipped from the standard Cartesian coordinate system, with the origin in the upper-left corner and y increasing as you move down the screen. See right diagram below:
(This is adapted from Coordinate Systems in the Quartz 2D Programming Guide. The original diagram in the Apple documentation is merely illustrating how the coordinate systems are flipped, but I've changed the arrow to more accurately represent how this affects the drawing of an arc from 0 to π/2.)
The result is that, when using the iOS coordinate system, it will start at 3 o'clock but then proceed clockwise.

Because iOS draws everything upside-down.
In OS X (and just about every math book, and also by default in Core Graphics which came from OS X), the origin is in the lower-left corner and the Y-axis increases as you move up. In that coordinate system, the angles lay out the way you think they should. In UIKit's upside-down coordinate system, everything is flipped.
What's interesting is that the direction of the angles bothered you, but the bizarre Y-axis did not. (*) This inverted intuition among programmers is likely the reason that Apple flipped the coordinate system when they wrote iOS, but you can still see the artifacts here and there. (In fairness to Apple, layout code that mimics a page, like text views and scroll views, is much easier to compute when Y increases downward. Since those are very common design elements, it's not so crazy that UIKit flips the axes. It also goes to show that these things are very arbitrary in math and computers.)
(*) Yes, you noted where the origin was located, and that this was a likely part of the answer, but allow me some hyperbole to make the next point :D

Related

In what contexts is the coordinate space on iOS the (unflipped) default?

According to the documentation for CGRect
In the default Core Graphics coordinate space, the origin is located
in the lower-left corner of the rectangle and the rectangle extends
towards the upper-right corner. If the context has a
flipped-coordinate space—often the case on iOS—the origin is in the
upper-left corner and the rectangle extends towards the lower-right
corner.
I've always taken it at face value that the coordinate system on iOS starts on the upper-left, but after reading this, it makes sense that it's flipped, and not the default coordinate space. You don't think about points on a Cartesian graph the same way you do on iOS, where adding to the Y value shifts down, not up.
The documentation says it's 'often the case', so when is it not the case on iOS? And on what platforms is the coordinate space the Core Graphics default?
In iOS and UIKit, the origin is in the upper-left and positive y values go toward the bottom of the screen.
But for the lower level Quartz APIs, the origin is in the lower-left with y values going up toward the top of the screen.
This is covered in the Quartz 2D Programming Guide under the section titled Drawing to a View Graphics Context in iOS.
The default coordinate system used throughout UIKit is different from the coordinate system used by Quartz. In UIKit, the origin is in the upper-left corner, with the positive-y value pointing downward. The UIView object modifies the CTM of the Quartz graphics context to match the UIKit conventions by translating the origin to the upper left corner of the view and inverting the y-axis by multiplying it by -1. For more information on modified-coordinate systems and the implications in your own drawing code, see Quartz 2D Coordinate Systems.
So the "often the case" is when using UIKit. It's not the case when using lower level Quartz APIs.

how to find orientation of a picture with delphi

I need to find orientation of corn pictures (as examples below) they have different angles to right or left. I need to turn them upside (90 degree angle with their normal) (when they look like a water drop)
Is there any way I can do it easily?
As starting point - find image moments (and Hu moments for complex forms like pear). From the link:
Information about image orientation can be derived by first using the
second order central moments to construct a covariance matrix.
I suspect that usage of some image processing library like OpenCV could give more reliable results in common case
From the OP I got the impression you a rookie in this so I stick to something simple:
compute bounding box of image
simple enough go through all pixels and remember min,max of x,y coordinates of non background pixels
compute critical dimensions
Just cast few lines through the bounding box computing the red points positions. So select the start points I choose 25%,50%,75% of height. First start from left and stop on first non background pixel. Then start from right and stop on first non background pixel.
axis aligned position
start rotating the image with some step remember/stop on position where the red dots are symmetric so they are almost the same distance from left and from right. Also the bounding box has maximal height and minimal width in axis aligned position so you can also exploit that instead ...
determine the position
You got 4 options if I call the distance l0,l1,l2,r0,r1,r2
l means from left, r means from right
0 is upper (bluish) line, 1 middle, 2 bottom
then you wanted position is if (l0==r0)>=(l1==r1)>=(l2==r2) and bounding box is bigger in y axis then in x axis so rotate by 90 degrees until match is found or determine the orientation directly from distances and rotate just once ...
[Notes]
You will need accessing pixels of image so I strongly recommend to use Graphics::TBitmap from VCL. Look here gfx in C specially the section GDI Bitmap and also at this finding horizon on high altitude photo might help a bit.
I use C++ and VCL so you have to translate to Pascal but the VCL stuff is the same...

Why does DirectX use a flipped Y axis?

I am saving my driven X/Y coordinates, and then using a function that convert the coordinates to meters, and add 1280 to each point (so it will fit nicely into a 2560x2560 image), and then draw a polygon between the 'points', resulting in a some sort of racing line. But once I have generated the polygon and saved it as an image, it is vertically flipped somehow. Flipping the image vertically will make it match the track bitmaps perfectly. I was told this is due to DirectX internally has the Y axis flipped. Why does DirectX use a flipped Y axis?
Well, the question is, does DirectX have a flipped Y-axis or does the image?
DirectX uses a 3D/4D coordinate system where the X-axis points to the right and Y-axis points upwards when no transformation is applied. This is because the screen (where Y-axis points downwards) is the last instance that has to process the image. Every step before that uses the coordinate system with the upward Y-axis. Since Direct3D is designed for 3D worlds, a coordinate system that is aligned like the world and like most coordinate system in maths is much more convenient for the programmer and designer. Imagine, you would create a 3D model. Wouldn't it be kind of weird, if you design it so that the Y-axis is pointing downwards?
When you have no transformation at all that would allow perspective and so on, you have the same coordinate system. Ignoring the Z-axis, the top left corner is (-1 | 1), the bottom right corner is (1, -1). This is equal to the coordinate systems used in e.g. maths. In the end, this coordinate system is transformed with the viewport which will result in the top left corner to be (0 | 0) and the bottom right corner to be (ResolutionX | ResolutionY).
So all in all, the reason why the Y-axis points upwards is that Direct3D's main purpose is to describe worlds in a convenient way independently of the screen's physical attributes.

XNA and Matrices

So thanks to many of the replies from this board, I have a much better understanding of some of what's under the hood but I just need this little bit more to get a firm understanding. So I am reading through part of Riemer's tutorials here:
http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Coll_Detection_Matrices.php
I'll use the carriage example as it's fairly simple.
So the series of transformations for the carriage is this:
1: Matrix.Identity;
2: Matrix.CreateTranslation(xPos, yPos, 0)
3: Matrix.CreateScale(playerScaling)
4: Matrix.CreateTranslation(0, -carriage.Height, 0)
So my questions are these:
Riemer states:
1: If we would render the image just
like it is (or: with the Identity
transformation), it would be rendered
in its original size in the top-left
corner of the screen.
I don't get in what context this is applicable. Is he just referring to the fact that before the draw, all images start at the world origin of 0,0? Or is he saying that when these transformations take effect, the origin of the object will now be placed at the upper-left and translated back to the world origin?
2: First, the carriage image is moved so its top-left point is at the position specified as second argument in the SpriteBatch.Draw method.
Ok, so is he saying this is what happens under the hood for what happens during the draw method or that he is just passing the same parameter as what you send to the draw method?
4: Finally, and this is the most challenging step: the image is moved over the Y axis, since in our SpriteBatch.Draw method we’ve specified (0, carriageTexture.Height) as origin. Very important: it is moved over its own Y axis, which has been scaled down. So instead of being moved over 39 screen pixels, the carriages will be moved vertically over 39*0.4=16 pixels pixels (since carriageTexture.Height = 39 and playerScaling = 0.4).
Ok, so we've been positioning things using these matrices in our world/screen space. When you scale something down, I don't get why it will now start moving in accordance to the object's local space. For example, our first translation matrix moved according to the world/screen space but now he states "it is moved over its own Y axis".
Why is the identity matrix optional?
Thus, I am having trouble connecting back the draw method with these matrix multiplications, what the deal with the object going to the world origin is and why the create translation shifted its behavior.
1.1: Images are drawn at the upper-left hand corner by default on this system. Not all systems are like that, so it's worth pointing that out in the documentation. So if none of the transformations are applied (or only the identity one, which doesn't do anything), it will draw in the upper-left hand corner.
2.1: Once you've applied the transformation in line 2 it will translate (move) the image xPos, yPos across the screen. When exactly it happens isn't that important, but it'll probably be applied by the graphics card at draw time.
4.1: No, you've always been positioning by local space. It's just that until line 3, local space has been the same size as global space. Now local space is scaled, so translations will be scaled as well.
4.2: Most systems initialize matrices to the identity matrix. The identity matrix by definition doesn't do anything (if you multiply it with matrix A you'll get matrix A again). So if you omit it, it doesn't matter. It is useful for being explicit or for resetting a matrix later.

What is this rotation behavior in XNA?

I am just starting out in XNA and have a question about rotation. When you multiply a vector by a rotation matrix in XNA, it goes counter-clockwise. This I understand.
However, let me give you an example of what I don't get. Let's say I load a random art asset into the pipeline. I then create some variable to increment every frame by 2 radians when the update method runs(testRot += 0.034906585f). The main thing of my confusion is, the asset rotates clockwise in this screen space. This confuses me as a rotation matrix will rotate a vector counter-clockwise.
One other thing, when I specify where my position vector is, as well as my origin, I understand that I am rotating about the origin. Am I to assume that there are perpendicular axis passing through this asset's origin as well? If so, where does rotation start from? In other words, am I starting rotation from the top of the Y-axis or the x-axis?
The XNA SpriteBatch works in Client Space. Where "up" is Y-, not Y+ (as in Cartesian space, projection space, and what most people usually select for their world space). This makes the rotation appear as clockwise (not counter-clockwise as it would in Cartesian space). The actual coordinates the rotation is producing are the same.
Rotations are relative, so they don't really "start" from any specified position.
If you are using maths functions like sin or cos or atan2, then absolute angles always start from the X+ axis as zero radians, and the positive rotation direction rotates towards Y+.
The order of operations of SpriteBatch looks something like this:
Sprite starts as a quad with the top-left corner at (0,0), its size being the same as its texture size (or SourceRectangle).
Translate the sprite back by its origin (thus placing its origin at (0,0)).
Scale the sprite
Rotate the sprite
Translate the sprite by its position
Apply the matrix from SpriteBatch.Begin
This places the sprite in Client Space.
Finally a matrix is applied to each batch to transform that Client Space into the Projection Space used by the GPU. (Projection space is from (-1,-1) at the bottom left of the viewport, to (1,1) in the top right.)
Since you are new to XNA, allow me to introduce a library that will greatly help you out while you learn. It is called XNA Debug Terminal and is an open source project that allows you to run arbitrary code during runtime. So you can see if your variables have the value you expect. All this happens in a terminal display on top of your game and without pausing your game. It can be downloaded at http://www.protohacks.net/xna_debug_terminal
It is free and very easy to setup so you really have nothing to lose.

Resources