Benjamin Jessup wrote:
Awhile back I messaged about the development of a Bounding Box HitMap system for the FloatCanvas. Here is an update.
What are your thoughts for this code? I'm thinking that we can add an attribute to FloatCanvas that the user can set to determine which hit-test method is used.
To do that would require a little re-factoring -- currently, the HitDict holds information about what objects are bound, as well as the color of the hit-test bitmap. Also, the bitmap is being drawn, whether its used or not, now.
The binding code needs cleaning up anyway -- there should be more logic in the DrawObjects, and less in the Canvas, I think.
Note also that this won't work for unscaled object, that have no bounding box in world coordinates. Maybe hit-testing should be done in pixel coords?
This doesn't work for the mouse_over events either, though there may be performance issues if we tried that.
The HitTest() function of the FloatCanvas, in addition to identifying which objects bounding boxes contain the hitpoint, should determine which is on top by referencing the self._ForeDrawList and self._DrawList (in that order) through a python list index. I have attached the code below in case anyone else is interested or can give me pointers on how to improve this code. I will eventually have to develop a Z index which I believe can be attached to the FloatCanvas Object, but at first I would imagine each Z index will contain many objects, and ultimately the order will get determined by the _DrawList and _ForeDrawList once again.
I'm not sure about he Z-index approach. I don't know what to do with two objects that have the same Z value, for instance.
one way to make this code easier would be to loop through the draw lists, and check for the hit testing there, that would put it in all the right orders, but wouldn't work so well with the current HitDict...
What I've been thinking is that FC should support more methods to manipulate the z order:
move up move down move to top move to bottom add above this object add below this object That kind of thingTo do all that, and keep it a bit cleaner, I think we really should abstract out the DrawList and ForeDraw list into a class that supports all that, and FC just uses it. In fact, that class should perhaps be something like a document class that keeps track of all the objects, etc, leaving FC to do the actual drawing and all that.
Whether I'll ever have time for that, who knows? other comments;
def HitTest(self, event, HitEvent):
""" Hit Test Function for BoundingBox Based HitMap System"""
if self.HitDict:
#Get Mouse Event Position
xy = event.GetPosition()
xy = self.PixelToWorld( xy ) #Convert to the correct coords
objects = [] #Create object list for holding multiple objects
object_index_list = [] #Create list for holding the indexes
why not move this check to before getting the position, etc?
# check if there are any objects in the dict for this event
for key2 in self.HitDict[HitEvent].keys():
bb = self.HitDict[HitEvent][key2].BoundingBox
if xy[0] >= bb[0,0] and xy[0] <= bb[1,0] and xy[1] <=
bb[1,1] and xy[1] >= bb[0,1]:
The Bounding Box class has a PointInside method:
if bb.PointInside(xy):
Object = self.HitDict[HitEvent][key2]
objects.append([Object,xy])
no need to store xy, it isn't changing..I've included a somewhat re-factored version, in a demo that injects it into FloatCanvas for testing. The demo is now in SVN.
I'm off for a month, don't expect replies for a while! -Chris -- Christopher Barker, Ph.D. Oceanographer Emergency Response Division NOAA/NOS/OR&R (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception [email protected]
BB_HitTest.py
Description: application/python
_______________________________________________ FloatCanvas mailing list [email protected] http://paulmcnett.com/cgi-bin/mailman/listinfo/floatcanvas
