QGraphicsItem::setTransformOriginPoint bug when trying to scale image - c++

I have created my own class by extending QGraphicsItem and I want to make it so that when someone does a wheel even while over this item, it scales.
This way, i can have multiple items in a scene, and scale each of them in and out as I please.
The problem is, I want the item to scale under the mouse cursor, much like google maps does. That is, a move forward will keep panning the image and scaling it, so taht the area in the vicinity around my mouse pointer is always in view.
void ImagePixmapItem::wheelEvent ( QGraphicsSceneWheelEvent * event ){
update();
qreal factor = 1.2;
if (event->delta() < 0)
factor = 1.0 / factor;
scale(factor, factor);
scaleFactor *=factor;
this->scene()->setSceneRect(0,0,this->boundingRect().width(), this->boundingRect().height());
}
This is the code I am using to do the scale. The problem is, it always seems to be scaling from the top left corner. Well, this is undesirable, beacuse if I scale in or out too much, eventually my area of interest around the mouse pointer has moved off the screen, and I have to either scroll manually or pan to the location, zoom, pan, etc, until i get to the desired level.
I tried to use the QGraphicsItem::setTransformOriginPoint, but no matter what values I put in there, it still seems to scale and such from the top left.
What can I add to that code I posted to get the desired effect?

I have achieved similar functionality in my Image-Manipulation application (scaling the view and having the area under my mouse stay in place and visible) but I scale the whole graphics-view not a specific item, so I don't know if this code can solve your problem.
Anyway, this is what I do in the constructor of my subclassed QGraphicsView (after I set the scene):
setTransformationAnchor(AnchorUnderMouse);
setResizeAnchor(AnchorViewCenter);
I also use the above functions, after each call to:
MyGraphicsView->setTransform(transform);
I'm not sure if this can help you, but I hope so.

Related

Osmdroid - Marker - increase selection area to get the InfoWindow

When selecting a Marker an InfoWindow pops up.
Sometimes the selection of a Marker is difficult. Especially when the map is rotating in the direction of navigation.
How can I increase the 'touch circle' so that selection is easier?
Update: I have to change the hitTest() for the Marker by subclassing.
I would like to check whether the 'hit' (or touch) was within a circle of X pixels around the point of the Marker. The icon will rotate while I navigate, so I guess I don't use the icon.
How can I do that?
public boolean hitTest(final MotionEvent event, final MapView mapView){
final Projection pj = mapView.getProjection();
pj.toPixels(mPosition, mPositionPixels);
// Does mPositionPixels contains the x, y of the Marker?
// Should I draw a Rect around this point, or could it be a circle?
// How can I check whether the event.getX(), event.getY() is a hit?
return hit;
}
Method proposed by spy is feasible.
You can also create your icon bitmap with an area of transparent pixels around. This is a very simple way to increase its touch area.
I believe #Mker would say, extend the Marker class and override the method hitTest. That is used for the Marker itself. I'm not sure if you can change this for the InfoWindow itself.

MapView.zoomToBoundingBox() not zooming

I'm trying to zoom the map to a specific bounding box. I know I have to make the call AFTER the layout of the map is ready, so that is not the problem. The camera only gets centered on the bounding box, but it doesn't zoom as closely as possible, it just stays at whatever zoom level was set previously. What am I missing? How do I make it zoom as well?
The class MapController in the API allows to move and animate the map. Maybe you can look the zoomToSpanmethod.

Qt - Using a QTransform (or similar), scale inner QRect to/from QGraphics

Some background -
Say you have QGraphicsScene, and only one view, which is a 1-1 scale with the scene.
You have a QRect A, which is represents an external view of the scene, with a pre-defined pixel size.
You have a QRect A1 which is a smaller rect inside of A.
How do you translate A1 to the scene, such that it is scaled correctly (i.e. if it's 1/4 of rect A, it will occupy 1/4 of the scene), and then undo that transform to scale a rect created in the scene to fit in rect A correctly?
I can do all this brute force, but I'm wondering if there's a way using Qt's built in classes...
After looking over some examples to try and find similar uses, I realized I'm totally missing the point - I can just set A/A1 directly to the scene, and scale the view (via the totally obvious but somehow completely overlooked until now QGraphicsView::fitInView(..)) to fit the rects inside. No rect transforms necessary. Total 'duh' moment. :)
I will need to transform mouse clicks and points in the view when interacting with it, but there is a whole nice set of mapTo* mapFrom* that will handle that nicely.
TL;DR - Use fitInView()

Map Editor Performance Advice

First of all don't think I'm making a "SFML and/or C++ performance Issue" type question. I'm not satisfied with the performance of this map editor I've been working on and I'm 99% percent sure I'm at fault for it.
Currently how I place tiles on the map is basically I have a function that loops through every single tile on the map and checks if the mouse is hovering over it. I call this function inside another function simply titled handleMouseClick()
This is plenty functional if you were just clicking each time you wanted to place a tile, however I have it sort of like a paintbrush. Even if there's only 500 tiles on the map, it will skip tiles if you drag it across the screen quickly. I need to be able to create maps that have 5000+ tiles and I can't afford so-so performance.
I've looked over my code and made sure I'm not making unnecessary copies. I'm pretty sure that the best way to increase performance would be to change how I check which tile the mouse is changing.
The only idea I have is to have the map in "chunks" so that it will check the tiles of the "chunk" the mouse is in.
Use math. Lets say you have tiles with pixel dimensions {tile.width, tile.height}. And your application's window is a view of the map, and the top left corner of the window is on pixel {view.x, view.y}. And the mouse position, relative to the top left corner of the window is {mouse.x, mouse.y}. You can calculate which tile the mouse is pointing to with the following:
transformed_mouse.x = mouse.x + view.x;
transformed_mouse.y = mouse.y + view.y;
mouse_tile.x = transformed_mouse.x / tile.width;
mouse_tile.y = transformed_mouse.y / tile.height;
For handling a dragging effect where the event system doesn't update fast enough, keep track of where the mouse was for the previous iteration, and use Bresenham's line algorithm to fill in all the tiles between the tile which the mouse is currently pointing to, and the tile which the mouse was pointing to previously.

Handing a touch on a rotated CCLayer

After I rotate a CCLayer, my boundingBox grows, instead of rotating. Perhaps to be expected.
My issue is, I'm relying on a user touch on this layer. When the layer is rotated as in the figure on the bottom of the attached image, the clickable area increases because I'm calling:
if(CGRectContainsPoint(clickableLayer.boundingBox, touchLocation))
This causes an issue because this bounding box after rotation is covering up other things that are also clickable.
How do I only perform an action if the actual layer is touched? I want something to happen when just the green box is clicked, not the boundingBox of the layer.
Thoughts?
You can use CGMutablePathRef to detect transparent part:
Refer my answer in this thread.
Information about How to create CGPath:Here
For more information, Click Here
This thread got me to my answer: http://www.cocos2d-iphone.org/forum/topic/272336