Rotate a Drawable in Android - c#

How do I rotate a Drawable in android?
I have a class that inherits from Drawable and overrides the Draw(canvas) method in order to create an arrow head that I need to place on a line and rotate it to match the slope of the line.
I cannot figure out how to rotate the Drawable; everything I've seen on this has been how to rotate a Bitmap, not a Drawable.
I have tried rotating the canvas first but that causes odd results.
Any suggestions?
The last thing I have tried that I have seen a lot of people discuss is this:
how to rotate a bitmap 90 degrees

So I figured it out. It seems there is a pretty specific way you must rotate the canvas in order to rotate a drawable on it:
canvas.Save(SaveFlags.Matrix);
canvas.Rotate(_degrees, _location.X, _location.Y);
canvas.DrawPath(path, _paint);
canvas.Restore();
So basically, you save the canvas' current state, rotate it (here, I'm using _location which holds a point in which the user lifted their finger from the screen), then draw on the rotated canvas and then restore it to it's previous state (with the drawable drawn still drawn).

Related

Why UI Element corners are equal to Canvas corners?

I'm building a game in Unity for Android in portrait mode. I have a Canvas as big as the display and the render mode is set to Screen Space - Camera. I also have a RawImage (child of the Canvas) colored in blue that I resized and repositioned in code to fit my needs. The problem came when I had to get the corners of the RawImage using the GetWorldCorners property of RectTransform. There was something wrong with the results and I finally found the problem, which is that even though the RawImage was resized and repositioned, the corners of the RawImage were the same as the corners of the Canvas. Look at the image below:
I selected the RawImage from the Hierarchy and currently, the corners of the RawImage are the ones pointed by the RED Arrows. But I need the corners to be the ones pointed by the GREEN Arrows.
Here is a simplified version of the resizing and repositioning function:
private void applyResize()
{
//The values of the Vector2s are the output, in the real function there is a formula that isn't relevant to this question
myRawImage.GetComponent<RectTransform>().sizeDelta = new Vector2(864, 864);
myRawImage.GetComponent<RectTransform>().anchoredPosition = new Vector2(0, -1178);
}
I am sure that the problem comes from the 2 lines of code in the above function since you can see in the image that even the Pivot has not changed. I need to find a way to adapt the corners to the repositioned and resized RawImage, not before it was modified. I can provide any additional information if needed. I will greatly appreciate any amount of help. Thank you in advance!
UPDATE 1:
The values of the offset position and the side are NOT fixed, they are calculated based on some of my parameters and based on the display size. The problem is not the values, they are right. As you can see, VISUALLY the RawImage has the right size(864x864) and it is in the right position on the Y axis (-1178). In the Inspector tab you can see that the RawImage is initially placed at the top and center side of the display. I modify it's position and size at Runtime. The problem is even though visually the RawImage is right, the anchors and pivot still remain the same as the Original, before calling the function. I need the corners of the RawImage to change based on the modified size and position. The goal here is to get the right corners of the RawImage because later on I need to draw a line containd within the RawImage so I need the right coordinates. I don't know any other way to approach this.

Why texture appear on Bottom Left with Frame Buffer Object

I'm trying to render to texture using FBO using OpenTK in C#.
When I try to render, everything show up and just fine except the texture is shown on bottom-left corner, I'm expecting it shown on the top left corner.
Also the Texture appear flipped in Y axis, So I need to modify the Texture Matrix after binding the Texture Target.
If I just bind my texture and draw the vertices, the sprite will appear on top-left corner.
The codes I use is looks exactly same from the official documentation.
I got 2 questions:
1. Am I doing it right to make the target texture show up properly by modifying the Texture Matrix?
2. How to make the texture target appear on top left corner?
Thanks in advance!
Actually Origin is at Bottom Left , therefore the FBO is getting displayed in the Bottom Left.
In the normal images , the texture space 0,0 is at top therefore you don't see it flipped.
So you have to add the texture matrix to make the space same.
When I try to render, everything show up and just fine except the texture is shown on bottom-left corner,
Yes. In OpenGL the origin (0,0) of 2D images (the viewport, textures, render buffers) is in the lower left.
I'm expecting it shown on the top left corner.
Why? The origin (as far as OpenGL is concerned) is in the lower left. Why'd you expect it in the top?
I encountered similar problems when the first time I tried FBO, so here my answer:
Although there several ways to workaround against this Upside down problem, Modifying Texture Matrix isn't bad idea at all. Sometimes modifying Texture matrix could be handy in certain situation, e.g: Use non normalized texture coordinate, So you can add such features to your bind texture function.
It's seems projection / viewport issue, if you are sure that the normal sprite appear on top-left coordinate, try to re-setup your projection / view / camera before unbind the FBO handle.

How do I create an image and save it for later to draw as texture in XNA?

In my game I need to draw a circle made of squares the sizes of a game tile (circle is made of squares). I could just draw monochrome square textures in form of a jagged circle each frame, but it consumes a significant amount of resources. What I'd like to do is to draw it somewhere in the memory just once and save to draw each frame after that.
I could simply draw said circle myself and use it as a ready texture, but my circle is not always the same. It has different size throughout the game (and it's not really a circle half of the time, but I've got the algo that says where to draw), so it has to be drawn programmatically.
First you render the circle to a custom RenderTarget2D. You can set a custom render target like this:
GraphicsDevice.SetRenderTarget(renderTarget);
After rendering your circle to the render target cast it to a Texture2D like this:
texture = (Texture2D)renderTarget;
Read more: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Render_to_texture.php

XNA Rotation Help(Interesting...)

Hello Stack Overflow users, I have a fun problem that I have in my XNA Game.
So basically I have an asteroid, 80x80, and I set the origin as imageW / 2, imageH / 2 (If order would matter, it wouldn't, the asteroid is a square).
Here is an image, explaining the problem! Visualization FTW :D
http://i.imgur.com/dsawS.png
So, any ideas on what is causing this? I spend 1 hour, I looked at examples, I found out it is supposed to rotate like this:
http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/rotation.jpg
But it's not.
Here is a code sample. I have a object named Drawable that has properties which hold the vector position, etc.
Vector2 asteroidOrigin = new Vector2(asteroidImgs[asteroid.asteroidType].Width / 2, asteroidImgs[asteroid.asteroidType].Height / 2);
drawableList.Add(new Drawable(asteroidImgs[asteroid.asteroidType], asteroid.asteroidPos, asteroid.angle, asteroidOrigin));
Here is the Draw Method:
foreach (Drawable drawable in renderManager.getRenderList)
{
spriteBatch.Draw(drawable.image, drawable.position, drawable.sourceRectangle, drawable.tint, drawable.angle, drawable.origin, drawable.imageScale, drawable.spriteEffects, drawable.depth);
}
And yes, the Drawable Class has multiple constructors and they assign default values.
When you define an Origin in SpriteBatch.Draw, you are defining the new point on your texture which will draw at the Position argument. Obviously this affects translation as well as your desired rotation. When you set the origin to the center of the image, the image is translated so that the center is at your Position, then rotated around that point. When you set the origin to Vector2.Zero, the translation is not changed, but the image rotates around its top left corner.
The solution is to either redefine what you mean as "Position" for sprites to be where the CENTER of the image draws on screen (I recommend this, makes things nice) or perform a bit of work before drawing by adding the Origin to the Position before calling Draw.
I, again, recommend the first solution, because then when you want to draw a circle in the center of the screen you can just set its position to be the center of the screen and be done. You won't need to take its size into account. And so on.

Create a polygon filled with a tiled image in c#

I'm creating an application which visualises a picture frame as the user designs it. To create the frame I am drawing 4 polygons which represent the physical bits of wood and using a TextureBrush to fill it.
This works perfectly well for the left and top edges. However, for the bottom and right edges this method isn't working. It appears to me that the TextureBrush is tiling from the point (0,0) on the image and not within the polygon I've drawn. As a result, the tile doesn't line up with the polygon. By adjusting the size of the image I can get the tile to line up perfectly.
How do I create an arbitrarily positioned polygon and fill it with a tiled image, starting from the point (0,0) within the polygon, not the canvas?
I'm not attached to FillPolygon and TextureBrush if there is a better solution.
Example
I've just found the answer. I was playing with adding a BoundingBox to the TextureBrush constructor but I kept getting OutOfMemory exceptions and thought it was me not understanding. Turns out it's a bug in the .NET framework
http://connect.microsoft.com/VisualStudio/feedback/details/90973/texturebrush-constructor-throws-out-of-memory-exception-when-providing-the-bounding-rectangle
The work around is to use a transformation to move the texture
var brush = new TextureBrush(new Bitmap(imagefile));
Matrix mtx = brush.Transform;
mtx.Translate(xoffset, 0);
brush.Transform = mtx;

Categories

Resources