I am using Dave Morrissey's gorgeous library https://github.com/davemorrissey/subsampling-scale-image-view , especially SubsamplingScaleImageView and I want image inside this view initialised with scale 100% and centered. There is method setScaleAndCenter(float, PointF), first parameter is scale, I set it to 1f, the second is point describing center but I don't know which values it should have.
My image has 2000x3000 px, I was trying set x and y of center point to 1000 and 1500, also I was trying something like 0.5f, 50 (percents) but it doesn't work.
How to calculate values for setScaleAndCenter(float, PointF) in order to center image?
Related
I have a question regarding transformations in OpenGL ES 2. I'm currently drawing a rectangle using triangle fans as depicted in the image below. The origin is located in its center, while its width and height are 0.6 and 2 respectively. I assume that these sizes are related to the model space. However, in order to maintain the ratio of height and width on a tablet or phone one has to do a projection that considers the proportion of the device lengths (again width and height). This is why I call orthoM(projectionMatrix, 0, -aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);and the aspectRatio is given by float aspectRatio = (float) width / (float) height. This finally leads to the rectangle shown in the image below. Now, I would like to move the rectangle along the x-axis to the border of the screen. However, I was not able to come up with the correct calculation to do so, either I moved it too little or too much. So how would the calculation look like? Furtermore, I'm a little bit confused about the sizes given in the model space. What are the max and min values that can be achieved there?
Thanks a lot!
Vertex position of the rectangle are in world space. A way to do this it could be get the screen coordinates you want to move to and then transform them into world space.
For example:
If the screen is 300 x 200 and you are in the center 0,0 in world space (or 150, 100) in screen space). You want to translate to 300.
So the transformation should be screen_position to normalized device coordiantes and then multiply by inverseOf(projection matrix * view matrix) and divided by the w component.
Here it is explained for mouse that it is finally the same, just that you know the z because it is the one you used for your rectangle already (if it is on the plane x,y): OpenGL Math - Projecting Screen space to World space coords.
I am currently using this gitup touchimageview https://github.com/MikeOrtiz/TouchImageView library.... After zoom,based on the zoom percentage I want to map the longpress coordinates to original image coordinates. Any help will be appreciated
Try to get matrix of ImageView:
float[] values = new float[9];
getImageMatrix().getValues(values);
With this array, you have position of top-left corner in terms of image on indexes 2 and 5. For example, when values[2], values[5] is -10,-10 it means, that left top corner of screen is 10,10 pixel of image. So, you can get coordinate of long press:
float imageX = (pressX - values[2])/scale;
float imageY = (pressY - values[5])/scale;
Recently I work with zoomed images, and use this library: https://github.com/chrisbanes/PhotoView
I think its a bit better, it have some predifined touches with image coordinates, and is still improved (last commit ~2 months ago)
I have an Image View which displays an image (e.g 2000x1000 pixels) and I have a coordinate (X,Y) on that image (not the image view). The canvas of my Image View is 600x800 for example. How can I convert the point (X,Y) to screen coordinate so that I can draw a path with them on the OnDraw(...) method of Image View. Any help is appreciated! Thank you.
Update: If I use matrix to draw the path between coordinates, it works but the path and objects i draw become really small. Here is the code i used.
final Matrix matrix = canvas.getMatrix();
matrix.preConcat( _view.getImageMatrix() );
matrix.preScale( 1.0f /_inSampleSize, 1.0f / _inSampleSize);
canvas.setMatrix( matrix );
//I draw the path here
Update: I add a picture to show the effect when using matrix to draw the path. I would like to have the 4 line and the 4 corner balls to be in normal size. The red color is the boundary of the Image View which holds the picture.
I think that might depend on how exactly you are displaying your image. Your ImageView (600x800) is not the same aspect ratio as your bitmap (2000x1000).
You are keeping the bitmap's aspect ratio stable as you scale it down? If so, which part (height or width) takes up the full screen and which has black (or whatever else) as padding? This will help you determine your scale factor.
scale_factor = goal_height/height1; //if height is what you are scaling by
scale_factor = goal_width/width1; //if width is what you are scaling by.
I would try:
x_goal = x1 * scale_factor;
y_goal = y1 * scale_factor;
That is, if you have a point (1333, 900) in your image, and your image takes up the full width, you would multiply both x and y by 600/2000 to get (399.9, 270). (you might want to round that decimal).
If you are NOT keeping the bitmaps aspect ratio stable (that is, you're squeezing it to fit), then you'd have a height_scale_factor and a width_scale factor. So you'd take (1333,900) and multiply x by 600/2000 and y by 800/1000 to get (399.9,720).
I have some sprites (Well, custom classes that implement Sprite, but whatever) that I resize. AndEngine resizes the image from the center, which makes an image placed at 0,0 no longer appear at 0,0. To fix this I applied
sprite.setScaleCenterX(0);
sprite.setScaleCenterY(0);
This places the image where I want it. However, now when I rotate the image, the image moves around (If the image were a plain square, rotating it should make no visible change). To fix this I applied
sprite.setRotationCenterX((sprite.getWidth() * sprite.getScaleX()) / 2);
sprite.setRotationCenterY((sprite.getHeight() * sprite.getScaleY()) / 2);
(For some reason, resizing a Sprite doesn't change the dimensions of the sprite, just the visual image, hence multiplying it by the scale). This, however, did not correct the problem, but merely changed where the image moved to when flipped.
Is my math off here? Wouldn't this center the rotation on the image so that the image doesn't move position? Or is there something else I'm missing?
Below is full code:
Sprite sprite = new Sprite(0, 0, singleTrackTR, getVertexBufferObjectManager());
sprite.setScale(scaleX, scaleY);
sprite.setScaleCenterX(0);
sprite.setScaleCenterY(0);
sprite.setRotationCenterX((sprite.getWidth() * sprite.getScaleX()) / 2);
sprite.setRotationCenterY((sprite.getHeight() * sprite.getScaleY()) / 2);
All your code is correct. I tried it myself, both the setProperty(x, y) and the setPropertyX/Y(a) versions.
By any chance, do you have it connected to a Body? Note that the Body also doesn't scale with a Sprite's setScale. It has its own setTransform method, which takes x and y (that you both have to divide by PhysicsConstants.PIXEL_TO_METER_RATIO_DEFAULT) and a rotation value.
I am developing a game for Android using LibGDX. I have to objects in the game that need to be rotated. The objects are a board, and a tube. The problem that I am having is this, the tube piece consists of three pieces, the center piece, and the end pieces. The tube and the board can be stretched. Because they can be stretched the end pieces have to be separate graphics so that they do not become distorted from being stretched. I am having a really hard time figuring out how to do this properly. The position and rotation are retrieved from a Box2D body.
This is what the object looks like once constructed:
tube piece with end caps http://weaverhastings.com/tube.png
This is the end piece:
end cap for the tube http://weaverhastings.com/tube_endpiece.png
This is the piece that goes in the middle:
middle piece for the tube http://weaverhastings.com/tube_middle.png
From looking at it, it looks like the problem is the origin. As the object is stretched out, the origin for the rotation of the end pieces needs to change. But I cannot figure out how to calculate that origin correctly.
Here is the code that I am using right now:
// Right border
batch.draw(border, // AtlasRegion for the border
position.x, // The position as reported from box2d body
position.y,
25 + 150 * scale.x, // 25 is 2 x the end piece width, 150 is the width of the middle piece, it is multiplied by the scale because it can be stretched.
height/2, // This is just the height of the tube piece
border.getRegionWidth(), // the is the width of the border
height,
0.6f, // The scale of the borders is fixed
0.8f,
rotation * MathUtils.radiansToDegrees); // the rotation as retrieved from box2d body
// Left border
batch.draw(border,
position.x,
position.y,
25 - 150 * scale.x,
height/2,
border.getRegionWidth(),
height,
0.6f,
0.8f,
rotation * MathUtils.radiansToDegrees);
A video can be seen of the tube piece rotating here: http://youtu.be/RusL4Mnitds
Any help would be greatly appreciated. Thank you for reading this far.
In Libgdx the origin of rotation is relative to the objects position, eg, where you tell it to be drawn.
So for the left border you would need to say the originX would be half the width of the center piece (middlePiece.width/2) or whatever and for the right piece the originX would need to be negative this value(-middlePiece.width/2). Their positions of course would need to be at the ends of the centre piece when not rotated. The OriginY for each of them would be half the height of the Center piece. (middlePiece.height/2)
Hope this helps