QGraphicsPathItem hoverEvents - suppress hover on area formed by the path - qt

https://www.dropbox.com/s/phven3rriv36893/graphicsview-pathitem.png?dl=0
I wonder if there's a way to make my QGraphicsPathItem respond to mouseHoverEvents to the actual curve instead of the whole orange area as seen in the docs.
https://www.dropbox.com/s/7m8w34nitp34sgf/pipes.png?dl=0
In my application I'm not seeing the area that actually forms the path and therefor I only want a hoverEnterEvent when the bezier curve is hovered (and a hoverLeaveEvent when the bezier is left of, course).
Is that possible to achieve with QGraphicsPathItem or is that a completely wrong approach? If yes, how? If not, what QGraphics object can be considered as a replacement?
If code is really needed, let me know.
Cheers,
Michael

Tim Wakeham's answer is totally correct: you need to re-implement shape() to provide a more detailed shape for your path item. However, his answer is not totally useful, since it's not trivial to implement a good shape() method returning the right QPainterPath.
It's even more confusing because in this case, the QGraphicsPathItem can already provide a QPainterPath from its path() method. Unfortunately that is generally not the right value to return from the shape() method since it draws the item rather than delimits its outside.
Fortunately, since this is a fairly standard requirement, there is a built-in class to transform the path into an outline that can be used for the shape: QPainterPathStroker.
Here's some code I use to do that:
qp = QtGui.QPainterPathStroker()
qp.setWidth(MARGIN)
qp.setCapStyle(QtCore.Qt.SquareCap)
shape = qp.createStroke(self.path())

You need to reimplement QGraphicsItem.shape to return a more accurate representation of your curve. The default implementation gives you the bounding box as you've discovered.

Related

How do I adapt AStar in Godot to platformers?

I've been looking for a robust method of pathfinding for a platformer based game I'm developing and A* looks like it's the best method available. I noticed there is a demo for the AStar implementation in Godot. However, it is written for a grid/tile based game and I'm having trouble adapting that to a platformer where the Y axis is limited by gravity.
I found a really good answer that describes how A* can be applied to platformers in Unity. My question is... Is it possible to use AStar in Godot to achieve the same thing described in the above answer? Is it possible this could be done better without using the built in AStar framework? What is a really simple example of how it would work (with or without AStar) in GDscript?
Though I have already posted a 100 point bounty (and it has expired), I would still be willing to post another 100 point bounty and award it, pending an answer to this question.
you could repurpose the Navigation2D node for platformer purposes. The picture below shows an example usage. The Navigation2D node makes it possible to navigate the shortest path between two point that lie within the combined navigation polygon (this is the union of all NavigationPolygonInstances).
You can use the get_simple_path method to get a vector2 array that describes the points your agent/character should try to reach (or get close to, by using some predefined margin) in sequence. Place each point in a queue, and move the character towards the different points by moving it horizontally. Whenever your agent's next point in the queue is too high up to reach, then you can make the agent jump.
I hope this makes sense!
The grey/dark-blue rectangles are platforms with collision whereas the green shapes are NavigationPolygonInstance nodes
This approach is by no means perfect. If you were to implement slopes into your game then the agent may jump up the slope instead of ascending it normally. It is also pretty tedious to create all the shapes needed.
A more robust solution would be to have a custom graph system that you could place in the scene and position its vertices. This opens up the possibility to make one-way paths and have certain edges/connections between vertices marked as "jumpable" only. This is a lot more work though if you can not find any such solution online.

How expensive are QPainter::save() and QPainter::restore()?

I want to build a scene graph to store and manage my scene layout which will be painted using QPainter (like QPicture, but the layout should be modifiable).
The scene graph will contain nodes for transformations, clipping and primitives. The first two will need to store the current state of the painter to restore it afterwards. It seems natural to use QPainter::save() and QPainter::restore() respectively.
I am a bit concerned about the efficiency of these two functions. Qt's documentation gives no information here. Looking at Qt's source code, it seems
QPainter::save() copies every element of the state, e.g. the pen, the brush, the transformation, the clipping path, and many many more. It seems to me that storing the former state of the one or two relevant properties that I actually need by myself is far more efficient. Has anyone any experience with this?

Entity Relationship Diagram - ISA direction

In ERD I am used to see something like:
But I ran into some cases where the triangle is upsidedown, like:
So I wondered, does the direction of the ISA triangle matters? It seems only logical that the pointy vertex would point at the parent, and inheritants would go from the edge itself.
There's no inherent meaning in the orientation of the triangle. In your examples, they mean exactly the same thing. Different tools might implement it differently, and there are other conventions for subtyping besides triangles.
I suggest you pick the more popular convention and stick with it.

How to generate recursive shapes like geokone.net using GL.Begin?

http://app.geokone.net/ is an open source javascript app for generating shapes (if you can look at it, it's really fast, for 5 seconds, I'm sure you'll get the idea).
It's hard for me to go through it because it's a lot of code, what is the general idea?
also, I need those shapes as GameObject with polygon collider around them (anything from 0 to 20 of them on the screen at the same time, could be different shapes also), is it even possible with GL?
would GL help me? I think GL would be fast for just 1 shape or something (as it's using recursion), but for what I want, I think drawing them in real time to a texture, then using the texture as a sprite would be faster (as I can save the sprite for shapes that are the same), or maybe I should use a shader? any other method that you can think of?
and for the algorithm itself, what is the general idea?
You don't want to use GL, look into custom mesh generation with MeshFilter. It is required for the colliders anyway.
Meshes have to be updated just once and probably will be faster than any optimisation you proposed. You might need a shader to draw it, though.
As for the algorithm, I'm afraid you have to look into it yourself or hire someone for it. StackOverflow is for helping with issues, not doing the work for you. If you need a hint, look into basic fractals

Does the point lie in the region?

I am doing this in my paintEvent
painter.drawPie(rect, angle*16, 45*16);
But before drawing the pie I want to know whether the current mouse position lies under the pie region or not.
Mouse tracking is on. And I can get the mouseEvents. No problem from that side. But what is the math involved to know wheather the point lies inside the pie or not?
It's unfortunate that QPainterPath doesn't have an addPie() function. You can, however, use Qt's implementation of QPainter::drawPie() as a reference:
http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/painting/qpainter.cpp#line4439
You can essentially create the QPainterPath the same way they do it and call contains() on it.
I have not tried this, but you could try to intersect two QPainterPaths (one triangle and one circle) to get a QPainterPath for your pie-segment and then call QPainterPath::contains(QPointF&) with the mouse position as parameter.
Now that I write this, the check is probably easy to implement: if the point is inside the circle and inside the triangle, then it's inside the pie. Both subtests are easy to implement.

Resources