September 2015


Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Tschanen Miriam <[log in to unmask]>
Reply To:
MASON Multiagent Simulation Toolkit <[log in to unmask]>
Tue, 15 Sep 2015 09:03:59 +0000
text/plain (83 lines)
Hi Sean,

Thanks for your input. As it turns out, caching the graph as an image is actually slower than redrawing it, and causes a stack overflow for zoom levels above 40 (probably because my implementation caches the entire scene, and not just the visible part). I don't think it's feasible to draw and cache only the visible part for graphs, detecting which edges intersect/are contained within the clip is too complicated. I might consider it at a later stage, if it can be done without too much of an overhead.

About isDirtyField(), I'd thought as much, but thanks for clarifying. I was trying to catch resize/scale events from the display directly, but just comparing the clips seems like the better idea. Either way I've given up on the idea of caching for now, it doesn't seem to work well with my simulation.

Von: MASON Multiagent Simulation Toolkit [[log in to unmask]]&quot; im Auftrag von &quot;Sean Luke [[log in to unmask]]
Gesendet: Montag, 14. September 2015 20:36
An: [log in to unmask]
Betreff: Re: Caching Portrayals as Images

isDirtyField() is just a convenience flag that can be set by YOU to indicate that your data has changed.  MASON never touches it.  What you need is to be told that MASON has changed what it's displaying (in terms of scaling or scrolling).  This is easy:

public boolean somethingChanged(DrawInfo2D old, DrawInfo2D new)
        return (old.clip.getX() != new.clip.getX()) ||
                (old.clip.getY() != new.clip.getY()) ||
                (old.clip.getWidth() != new.clip.getWidth()) ||
                (old.clip.getHeight() != new.clip.getHeight()));

Now when you create a new buffer, store the buffer and also store the DrawInfo2D you had received.  When you get a new draw request, compare it against the new DrawInfo2D as shown above, and if "something changed", update the buffer and store the new DrawInfo2D instead.

Also: if info.precise is true, I would not buffer, but rather, I would draw directly and bypass the buffer entirely.


On Sep 14, 2015, at 9:12 AM, Tschanen Miriam <[log in to unmask]> wrote:

> Hi Ernesto,
> Thanks a lot for your response, it pushed me into the right direction. I ended up overriding the portrayal draw method as follows:
> public void draw(Object object, Graphics2D graphics, DrawInfo2D info) {
>     if(isImmutableField()) {
>         if(isDirtyField()) {
>             buffer = new BufferedImage((int) info.draw.width, (int) info.draw.height, BufferedImage.TYPE_INT_ARGB);
>             drawGraph(buffer.createGraphics(), info);
>             setDirtyField(false);
>         }
>         graphics.drawImage(buffer,0,0,(int) info.draw.width,(int) info.draw.height,null);
>     } else {
>         drawGraph(graphics, info);
>     }
> Just swapping out the graphics object (in my drawGraph method) is all that seems to be needed to make an image instead of drawing into the display directly.
> The display is working fine, except when resizing the window or using the scale buttons. As you mentioned I need to catch resize / scale events and set the dirtyField variable to make it work - do you know how to do that? I can't find a way to register for these events.
> Cheers,
> Miriam
> Von: MASON Multiagent Simulation Toolkit [[log in to unmask]]" im Auftrag von "Ernesto Carrella [[log in to unmask]]
> Gesendet: Dienstag, 8. September 2015 11:13
> An: [log in to unmask]
> Betreff: Re: Caching Portrayals as Images
> Hello,
> I have never done this so hopefully somebody will give you a better suggestion but  Display2d (and cognates) is a JComponent so you should be able to attach the portrayal to the display2d, feed a BufferedImage's graphics object to the display2d paint(g) method and get a fixed image out of it. Something like this:
> You'd probably have to listen to resize events to redraw the image and so on, but it may be what you are looking for.
> Portrayals have their own draw(g,x,y) method so there might be a faster, direct way of painting images from them but I am not really sure what the DrawInfo2D argument would look like.
> Good luck.
> On Tue, Sep 8, 2015 at 9:26 AM Tschanen Miriam <[log in to unmask]> wrote:
> Hi all,
> A while ago I mentioned that I was trying to display static JUNG graphs with a MASON portrayal class. The display is working very well at the moment (in no small part due to the help I received), but constantly redrawing the graph is putting a heavy load on my system. If I remember correctly, Sean suggested caching the graph as an image and redrawing that instead, since the underlying data never changes. This should give me a nice boost in performance.
> I was hoping someone could give me a few pointers on how to actually do that. There's a tutorial about displaying an image in a portrayal in the MASON How-Tos (, but I can't figure out how to store my graph as an image in the first place. There must be a way to rewire the output of my portrayal class to draw directly into the image. Any help would be much appreciated.
> Cheers,
> Miriam Tschanen