swarm-support
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: drawing pixmaps on rasters


From: Paul Johnson
Subject: Re: drawing pixmaps on rasters
Date: Mon, 13 Jan 2003 08:46:15 -0600
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.0.1) Gecko/20020918

Dear Aris:

I have one project where there are 5 rasters drawn side-by-side into a single raster. Here's an example:

http://lark.cc.ku.edu/~pauljohn/ResearchPapers/APSA01/fig2a.gif

In this one, I have 5 columns and 1 row, but the approach I describe below works for as many rows and columns as you want.

If you want something like that, and that's what I think you mean, here is how I did it.

Create one giant raster that is has enough space to hold M x N rasters, where N is the number of columns of rasters and M is the number of rows. I wanted a blank pixel between them, so I actually create a raster that has (X x M) + M pixels of height and (Y x N) + N pixels of width.

In the Observer level, created the giant raster with space

 {
  char rasterName[20];
  sprintf(rasterName,"feature%02d",i);
    worldRaster = [BatchRaster createBegin: self];
    worldRaster = [worldRaster createEnd];
    [worldRaster setColormap: batchColormap];
    [worldRaster setWidth: worldSize*N + N
                 Height: [[modelSwarm getHomeGrid:0] getSizeY] *M+ M ];
    [worldRaster pack];                           // draw the window.
  }


So then the problem is to have the agents draw the correct part of that giant raster. I am cutting and pasting from different parts of the program to give you an idea of how I do that.

In my case, each agent wrote a full row of N rasters, but I think you
will be able to adapt.

A method "writeRasters" in Observer is scheduled to do the writing.

As I recall, the tricky part was controlling the horizontal positioning of the part of the raster on which the agents draw. In the Observer class, I make this work with 2 methods. Note I have an instance variable "currentNhood" which controls which ROW I'm writing on.


- writeRasters
{
  int i;
  id rasterObject;
  char filename[40];

    int run=[parameters getRunArg];

    currentNhood=0;
    for ( i = 0; i < N; i++)
        {
[[modelSwarm getHomeGrid: i] passThroughToAllCells: M(drawSelfBatch)];
          currentNhood++;
        }

    if((getCurrentTime() % 500 ==0) || (end == 1))
        {
          sprintf(filename, "R%dt%06ld.ppm", run, getCurrentTime());
          rasterObject= worldRaster;
          [rasterObject  writeSelfToFile: filename];
        }
 return self;

}

This code uses the MultiGrid2d class I announced a while ago, but if you are using a regular Grid2d, you just need to tell each cell to draw itself with a method like "drawSelfBatch".

The last vital part is the Observer's method to draw on the raster. The first argument controls the position from left-to-right, which column is being drawn, while the IVAR in Observer, currentNhood, controls up-and-down positioning.

- drawFeature: (int) f PointX: (int) posX Y: (int) posY Color: (int) type {
    {
      id drawingRaster= worldRaster;
[drawingRaster drawRasterPointX: ((f+posX)+(f*worldSize) ) Y: (currentNhood+ posY)+(currentNhood*worldSize) Color: type];
    }
   return self;
}


Now, inside the agent that is doing the drawing, it is aware only of its need to draw, and it tells the observer how to do it. It tells the observer which column to draw in. In this model, a "feature" is a column.


- drawSelfBatch
{
  float color;
  int feature;

  for(feature=0; feature< numCultureFeatures; feature++)
    {
color= 66 + 80* (double) [self getAvgCultureFeature: feature] / (double) (numCultureTraits-1); [observerSwarm drawFeature: feature PointX: x Y: y Color: (int)color+0.5];
    }
  return self;
}





Aris Alissandrakis wrote:
Hello,

In my swarm simulation, every agent has its own display and raster. For demo
purposes,  I want to make some movies of simulation runs. I can capture each
individual display into a pixmap and then get lots of png files to make
movies of the events on each display, but I would like to somehow combine
all the displays in one (bigger) display which I can then save and make a
movie that shows what all the agents do at the same time...

So I thought of capturing the agent rasters into pixmaps, and drawing them
(placed appropriately) on another (larger) raster which I can then capture
as a pixmap and save into a png file...

My code looks like this:

first I create the bigger raster for the movie:

      movieRaster = [Raster createBegin: [self getZone]];
      [movieRaster setWindowGeometryRecordName: "something"];
      [movieRaster createEnd];
      [movieRaster setColormap: colormap];
      [movieRaster setWidth: 480 Height: 560];
      [movieRaster pack];

then I create a pixmap that captures the agent raster,

      aPic = [Pixmap createBegin: [self getZone]];
      [aPic setWidget: anAgentRaster]; //captures the agent raster
      [aPic setDecorationsFlag: YES];
      aPic = [aPic createEnd];

and then I try to draw the pixmap into my big movie raster:

      [aPic setRaster: movieRaster];
      [aPic drawX:10 Y:10];

or I could also/either do this:

      [movieRaster draw: aPic X: 30 Y: 50];

if I save the *agent pixmap*, the resulting png file is fine...

      [aPic save: filename];
      [aPic drop];

but...

      moviePixmap = [Pixmap createBegin: [self getZone]];
      [moviePixmap setWidget: movieRaster];
      moviePixmap = [moviePixmap createEnd];

      [moviePixmap save: differentFilename];
      [moviePixmap drop];

      [movieRaster drop];

...my problem is that when the movieRaster/Pixamp is drawn/saved,
instead of containing the (smaller) agent rasters drawn at the (10,10)
or (30,50) coordinates, I only get white dots there!
(see .png file attached)

Therefore I must be missing something, but I can't think of anything...
Perhaps when I capture the agent raster? But this gets saved fine on its
own...

is there anythig wrong with the draw method of either
the pixmap (once it's raster has been defined)
or the raster itself (using a pixmap) ?

The original agent rasters are ZoomRasters,but that shouldn't matter (?)

Any suggestions on missing steps/typos/syntax on this approach? I can't
really draw everything *originally* in one display and then capture that
(the number of agents can vary), and perhaps I can use some image software
to combine the different pictures, but I should be able to do this with
Swarm...


Aris Alissandrakis
------------------------------




--
Paul E. Johnson                       email: address@hidden
Dept. of Political Science            http://lark.cc.ku.edu/~pauljohn
University of Kansas                  Office: (785) 864-9086
Lawrence, Kansas 66045                FAX: (785) 864-5700


                 ==================================
  Swarm-Support is for discussion of the technical details of the day
  to day usage of Swarm.  For list administration needs (esp.
  [un]subscribing), please send a message to <address@hidden>
  with "help" in the body of the message.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]