I have a canvas that is drawing a circle with predefined bounds.
canvas.drawCircle((float) (getBounds().right / 2), (float) (getBounds().bottom / 2), (float) (getBounds().right / 2), paint);
and now I need to make it draw a square instead of a circle. so this is what I modified
(getBounds().right / 2) instead of it dividing by 2 I didn't divide it by anything for the radius
how ever it just overflows.
So this is how it looks like when its a normal circle.
and this is how it looks when I attempted to make it a square
can someone please suggest me how I can draw a successful square with the bounds I have been given?
Look's like the answer was fairly simple.
all I had to do is pass my rect and paint to Canvas::drawRect
here is the code
Rect rect = drawable.getBounds();
canvas.drawRect(rect, paint);
and image of the result
Related
What I'm trying to do:
Create a compass when given a direction in degrees (0 - 360). Like so:
What I have done:
I have managed to get the SVG image to point in the right direction but I can't seem to get it to rotate around the circle. To attempt a solution around the circle, I have decided to try get the positioning using the ellipse tool and this formula. This is what it looks like at the moment:
(notice how the arrow faces a different direction to the ellipse, in the circle, on the axis - given the center point is the middle of the green circle)
void setDirection(float value, int radius) {
fill(secondaryColour);
float origin_x = (1280 - (width-400)/2);
float origin_y = height/2;
float x = origin_x + radius * cos(radians(value));
float y = origin_y +radius * sin(radians(value));
//grey circle
ellipse(x, y, 20, 20);
//arrow SVG
pushMatrix();
translate(200, 300);
rotate(radians(value));
scale(0.5);
shape(arrow);
popMatrix();
}
Please note: value is in degrees and radius is the radius I want the arrow to sit on. What am I doing wrong with the ellipse? and how can I bring them both together?
I found that the starting angle started on the white line, but I was assuming it would start on the red (similar to the angle of the arrow). To resolve the issue I needed to subtract 90 degrees from the variable value before converting it into radians.
How to have rotated ellipse Shape in java? I.e. so that its semi-axes are not parallel to coordinate axes?
P.S. I need not just draw this ellipse but have it in memory as a shape object.
Just take an Ellipse2D object and apply an AffineTransform rotation to it, no?
AffineTransform.getRotateInstance(Math.PI / 4)
.createTransformedShape(new Ellipse2D.Double(0, 0, 2, 1));
How can we rotate a Image Clockwise using LibGDX? what i am looking is when a image is loaded,suppose a star, i need to rotate it from beginning of screen to end of the screen horizontally, with star rotating,how can i do that in libgdx?
When you draw the Texture with your SpriteBatch, you can use one of the draw functions that includes rotation. This javadoc has all the draw functions: SpriteBatch
You can keep a variable for position and rotation, and increase the rotation and x component of the position each time you render to make it rotate while moving horizontally.
Libgdx gives you more then one way to do that:
You can use Scene2D and add an Image to your Stage. Image is a subclass of Actor, so you can add Actions to it:
Image myImage = new Image(myTexture);
myImage.addAction(Actions.parallel(Actions.moveTo(endX, endY, duration), Actions.rotateBy(degrees, duration)));
myImage.setPosition(startX, startY);
myImage.setOrigin(sizeX/2, sizeY/2);
stage.add(myImage);
In render you can then call stage.act(), which updates the position, rotation, scale... of all your Actors and then call stage.draw() which will call draw() for all your Actors.
Image allready handles the draw() so you don't need to care about that anymore.
You can also do it without scene2d, by updating everything yourself:
You can store a int rotationSpeed in degrees/sec
You can store a int moveSpeed in units/sec (maybe pixel but i would suggest to use camera or viewport and use your own unit, which is equal on all devices)
Store the float angle, which is the current rotation of your Texture
and store a Vector2 position, which contains the x and y position of your Texture.
If you want to move in x and y direction you can also store a Vector2 direction, which is a normalized Vector, giving the percent of movement in x and y direction, but thats a different story.
Then in your render(float delta) you update everything:
angle+=delta*rotationSpeed;
angl%=360; // Limits the angle to be <= 360
while (angle < 0) // Unfortunally the "modulo" in java gives negative result for negativ values.
angle+=360;
position.x+=direction.x*moveSpeed*delta;
position.y+=direction.y*movSpeed*delta;
spriteBatch.draw(yourTextureRegion, position.x, position.y, sizeX/2, sizeY/2, sizeX, sizeY, scaleX, scaleY, angle);
For clockwise rotation simply use a negative rotationSpeed or replace the angle+= with angle-=.
Hope it helps.
Following is the implementation to rotate any sprite
batch.draw(sprite,(Gdx.graphics.getWidth() - sprite.getRegionWidth()) / 2.0f,(Gdx.graphics.getHeight() - sprite.getRegionHeight()) / 2.0f,sprite.getRegionWidth()/2.0f,sprite.getRegionHeight()/2.0f, sprite.getRegionWidth(), sprite.getRegionHeight(), 1f, 1f,count, false);
if(count < 0.0f)
count = 360.0f;
else
count --;
Initially set counter to
private float count =360.0f;
You can also use the Scene2D actions. I have an example here with asteroid-type thing falling down the screen and rotating.
http://www.netthreads.co.uk/2012/02/09/libgdx-scene2d-demo-with-scene-transitions/
To rotate anticlockwise and horizontally..
create a textureRegion
then
Sprite sprite = new Sprite(textureRegion, 0, 0, 128, 128);
sprite.setPosition(++mX, 0);
angle++;
sprite.setRotation(angle);
sprite.draw(batcher);
You can do it too like this:
on your create method
sprite.setOrigin(sprite.getWitdh() /2f, sprite.getHeight() /2f);
sprite.setPosition( 0, 200 ); //200 it's a example
on your render(float delta)
sprite.setX( sprite.getX() + delta ).setRotation( sprite.getRotation() + delta );
Here is a simple to rotate an actor in libgdx. First you need to set the origin:
img.setOrigin(getWidth/2,getHeight/2);
And then you can rotate clockwise and anticlockwise according to your need:
img.rotate(2f); or img.rotate(-2f);
So the following sample worked for me (infinite rotation)
Method 1: (recommended)
loadingActor.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.rotateBy(360, 1)));
Method 2:
Image loadingActor = new Image(AssetsController.getInstance().getLoading());
loadingActor.setOrigin(Align.center);
final SequenceAction infiniteRotate = Actions.sequence();
infiniteRotate.addAction(Actions.rotateTo(0 , 0f) );
infiniteRotate.addAction(Actions.rotateTo(360 , 1f) );
loadingActor.addAction(Actions.forever(infiniteRotate));
I'm trying to set up the renderer so that regardless of device, the view is a simple 2D field with the top of the screen at 1.0f and the bottom at -1.0f. I can't seem to get it quite right, I've been using the below method in the onSurfaceChanged() method and playing with the parameters in gluPerspective to achieve the desired effect, but it seems impossible to make perfect. Surely there is an alternative way to go about this to achieve what i'm after. I've also been playing with the Z values of the meshes drawn to try to get them to match.
Again i'm trying to set it up so that the screen is defined in the range -1.0f to 1.0, so that if you drew a square with sides equal to 2.0f it would fill the entire screen regardless of aspect ratio. What do I need to change to do this? (include the value I should use for the Z dimension of the mesh vertices)
(Don't be alarmed by the strange parameters in gluperspective(), I've been tinkering to see what happens.)
#Override
public void onSurfaceChanged(GL10 gl, int width, int height) {
if(height == 0) { //Prevent A Divide By Zero By
height = 1; //Making Height Equal One
}
gl.glViewport(0, 0, width, height);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
GLU.gluPerspective(gl, 90.0f, (float) width / (float) height,
0.0000001f, 100.0f);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
}
Generate a Ortho Matrix instead:
Matrix.orthoM(projectionMatrix,0,-yourdisplayWidth/2,+yourdisplayWidth/2,-yourdisplayHeight/2,+yourdisplayHeight/2,0f,2f);
So you can place your image-quads in distance of 1f in front of your camera. You also have to size your quads as big as they are in pixels. This way you can render pixelperfect.
See also: https://github.com/Chrise55/Llama3D
You might want to try experimenting with using glOrtho or glFrustum instead of glPerspective
If I have a canvas, on which I draw a Bitmap like this:
canvas.drawBitmap(bmLargeImage, srcRect, destRect, paint);
and I scale the bitmap:
canvas.scale(1.5f, 1.5f, 450, 250);
I want to get the position of the Bitmap after the scale. If the position before scale was (0, 0), after scale there is a offset and I need that offset.. how can I get it?
Thanks and sorry for the simple question, newbie here...
Ok lets try to work out the best formula for this
canvas.scale(scaleX, scaleY, pivotX, pivotY);
if (scaleX >= 1){
objectNewX = objectOldX + (objectOldX - pivotX)*(scaleX - 1);
}else{
objectNewX = objectOldX - (objectOldX - pivotX)*(1 - scaleX);
}
The same for objectNewY. The new width and height of the bitmap would of course be the multiple of the old size and scale.
I believe the cleanest Solution would be to use the underlying transformation Matrix of the Canvas you are manipulating.
In Android there is the canvas.getMatrix(Matrix cmt) method available which will yield it. The transformation matrix will transform any point in world space you throw at into screen coordinates. Just use the matrix.mapPoints(float[] points) and you will be fine.
FYI, you can easily do it the other way around too. If you want to know what screen coordinate maps to which point in world space, e.g. for tapping; the inverse matrix can be used for that. It can be obtained via the matrix.invert(Matrix out) method. Use its mapPoints() for the coordinate mapping then.
Here are the official docs:
mapPoints(), invert(), getMatrix()
If you'd like know the corners of your screen relative to your original canvas, you can use canvas.getClipBounds(). This returns a Rect with edge coordinates relative to your original canvas. For instance, if you start off with a canvas size of 320 x 480 and call
canvas.scale(2, 2, getWidth()/2, getHeight()/2);
and then
canvas.getClipBounds();
you will have a Rect (call this rect) where
rect.top == 120
rect.bottom == 360
rect.left == 80
rect.right == 240