ASE Home Page Products Download Purchase Support About ASE
ChartDirector Support
Forum HomeForum Home   SearchSearch

Message ListMessage List     Post MessagePost Message

  Creating closed polygon lines
Posted by DC Kelley on Jun-14-2011 06:33
Attachments:
I have been asked to model some roadway lanes in a street intersection, each with a width (that varies) and a center line path made up of short straight line segments.  I would of course prefer to use CD to do this, but offhand do not see a suitable example to learn from.

I have no problem creating the polygon set of points that represents each "side" of these object (and can plot them as layer as I have done with other X-Y chart data) but do not see a simple way to build a polygon, provide a fill color, and then render it.  Does a method like this exist?  [Aside: If I can keep in in the layers, then my analysis work of vehicle breadcrumbs over these zones may be easier]

I see a few notes about drawing polygons in the draw area, but have so far managed to avoid dealing with the draw area directly and none of the example seem to illustrate this area of the tool.  Plus, it seems the draw area uses integer math (which is fine) but I do not see any sort  of conceptual backgrounds on its limits.

I am confident this tool can do this, but not sure where to start on this.  Peter are there other references to be aware of for this topic?

As a graphic, here a nonsense lane-path that ideally I would love to create as a closed polygon and pass to the tool.
Regards, DCK
PolyQuestion.png

  Re: Creating closed polygon lines
Posted by Peter Kwan on Jun-15-2011 00:47
Hi DC Kelley,

If I were you, I will probably draw the polygon using the DrawArea.polygon as it seems easier for me.

If you would like to draw it without using DrawArea, one method is to draw it as a "bubble". ChartDirector allows you to use any polygon  shape as a bubble. See "DataSet.setDataSymbol4". The shape is always defined using a 1000 x 1000 canvas using integer coordinates, but you can scale it to any size you like (including using fractional values) after defining the shape.

We have not really tested the polygon code for extremely complex polygons (eg. polygons with 10000 vertices). Also, ChartDirector always uses the odd-even winding rule to handle self-overlapping polygons.

Hope this can help.

Regards
Peter Kwan

  Re: Creating closed polygon lines
Posted by DC Kelley on Jun-15-2011 06:14
If I were you, I will probably draw the polygon using the DrawArea.polygon as it seems easier for me.

Please correct me if I am mistaken, but this would then mean I lose any translation abilities between the two coor systems unless I do it myself.  And, to us, a key value of the CD tool is to be able to "not care" what bits lie in the display side of the problem and treat CD as a abstract drawing port.  It also seems to me that this part of the tool is not as well documented, at least when compared to the great job on everything else.

Is there any way to tell where a given X-Y point in a layer will end up before the entire charts contents are rendered?    And again, is this part of the tool documented in any further examples?  As you can no doubt tell, I am a bit concerned to go down that road.

If you would like to draw it without using DrawArea, one method is to draw it as a "bubble". ChartDirector allows you to use any polygon  shape as a bubble. See "DataSet.setDataSymbol4". The shape is always defined using a 1000 x 1000 canvas using integer coordinates, but you can scale it to any size you like (including using fractional values) after defining the shape.

To me this seems more promising for our needs, and I will investigate it further.  But it seems that polygon units are always in screen points, and how, when given another unit of measure (i.e 5 meters) is not clear to me how it can cope, esp when the final chart is not yet known, so a conversion factor to use is not yet known.

But how to precisely position it may also become the issue then, it would appear CD will attempt to use the center in this.  Can we tell it what point to consider the center?

These 'roadway' polygons are relatively simple, less than ~150 vertices and never overlapping, no holes etc.   And from what I know, it is not clear to me that this method will also allow me to remains oblivious to the underlying final bit image size.  Are we doomed to draw each image twice, the first time to determine the scale factors.

Regards DCK

  Re: Creating closed polygon lines
Posted by Peter Kwan on Jun-16-2011 01:09
Hi DC Kelley,

The limitation of the DrawArea method is that it either draws on the background of the chart (covered by everything except the background), or on the very top of the chart (covering everything else).

If you want to draw on top of the chart, you may obtain the DrawArea object by using "BaseChart.makeChart3". This creates the chart image. You can then draw on top of it using the returned DrawArea object. After makeChart3, you may also use XYChart.getXCoor and XYChart.getYCoor to translate from data coordinate to pixel coordinates. So if you want to draw a line from x = 10 to x = 100 (in x-axis units), you can use XYChart.getXCoor to translate them to x pixel units, and use them in the polygon.

For the "bubble method", if setDataSymbol4 is used, the canvas (the imaginery surface that you defined the polygon on) is always 1000 x 1000 in "arbitrary units". (It means the unit is not important. It exists just to allow you to specify the data points.) The actual polygon size can be specified in either x-axis units, y-axis units, or both, or in pixel units. (See LineLayer.setSymbolScale.) What happen is that ChartDirector will scale the polygon from the "arbitrary units" to the unit you want to use. Also, it will align the center of the "canvas" to the point you want to put the polygon to.

We use "arbitrary units" because in bubble charts, we only need to specify the bubble shape once, and we can draw the bubble shape in different sizes. (In bubble charts, we often have multiple bubbles of different sizes on the same chart.)

In either case (the DrawArea method and the "bubble" method), you do not need to draw the same chart twice.

Hope this can help.

Regards
Peter Kwan

  Re: Creating closed polygon lines
Posted by DC Kelley on Aug-17-2011 03:07
After a bit of investigation, neither of these solutions will really work for us.  The 'bubble" canvas is too limited (1000 points on a side) to represent a detailed curvature of a roadway lane spanning >100m, and the DrawArea method forces us to deal with screen pixel in a simple (not scale able) coordinate system the both takes away a primary benefit of the tool (CD more of less lets us ignore what range of data is to be displayed with its good auto scaling logic) and also really limits the ability to show the result between key layers (as Peter notes you can use it on the top or the bottom but not in between). Perhaps that last part could be overcome if we captured a PNG and inserted it into the layer we needed (most of  these road way polygons serve as a static base image).    This unforeseen limitation has caused a ton of frustration here over the last month or so.

Let me back off and take another swing at doing this. I clearly see the tool has the ability to do fills between lines, such as those shown in the Inter line code example.  Perhaps a call like  c->addInterLineLayer(line1, line2 ,etc) for every "lane" of interest.

If I were to arrange my polygons in some similar way perhaps this could be solved?  Perhaps I could use one side of the road as one line an the other along with a 'stop line' as the alternative line (between the two of them forming a closed shape and letting the layer do the surface work for me).   Peter please give me your thoughts. This is a problem I need to some up with a solution for.

  Re: Creating closed polygon lines
Posted by DC Kelley on Aug-17-2011 12:55
Allow me to add to this that I created a few line and they fill nicely but the problem with this is that the "edge" left or right is limited to a vertical line (and not at an angle as I needed).  I think that this may be a dead end unless Peter has a solution to suggest.

  Re: Creating closed polygon lines
Posted by Peter Kwan on Aug-17-2011 19:02
Hi DC Kelley,

I think the DrawArea method should be a workable method.

Concerning the use of pixel coordinates, you can define your roads using "data coordinates" instead of pixel coordinates, then use XYChart.getXCoor and XYChart.getYCoor to convert them to pixel coordinates.

To insert the polygon in between two layers, I think you may create the polygon in a separate DrawArea object, then use that DrawArea object as a symbol (see DataSet.setDataSymbol3) of another layer. You can then use Layer.moveFront or Layer.moveBack to insert the layer relative to another layer.

In C++, it is like:

.... create chart as usual ....

//auto-scale axis. After that you can convert from data coordinates to pixel coordinates.
c->layoutAxes();

// convert data coordinates to pixel coordinates relative to the plot area
std::vector<int> roadXPixels(dataLength);
std::vector<int> roadYPixels(dataLength);
for (int i = 0; i < dataLength; ++i) {
   roadXPixels[i] = c->getXCoor(roadX[i]) - c->getPlotArea()->getLeftX();
   roadYPixels[i] = c->getYCoor(roadY[i]) - c->getPlotArea()->getTopY();
}

//Now can use pixel coordinates to draw the polygon in a separate DrawArea
DrawArea *d = new DrawArea();
d->setSize(c->getPlotArea()->getWidth(), c->getPlotArea()->getHeight(), Chart::Transparent);
d->polygon(IntArray(&(roadXPixels[0]), dataLength), IntArray(&(roadYPixels[0]), dataLength), myEdgeColor, myFillColor);

//Add the DrawArea as a symbol of another layer
double centerX = (c->xAxis()->getMinValue() + c->xAxis()->getMaxValue()) / 2;
double centerY = (c->yAxis()->getMinValue() + c->yAxis()->getMaxValue()) / 2;
Layer *layer = c->addScatterLayer(DoubleArray(¢erX, 1), DoubleArray(¢erY, 1));
layer->getDataSet(0)->setDataSymbol(d);

//put the layer in front of another layer
layer->moveFront(anotherLayer);

(*** NOTE ***: I have not tested the code above. It only shows the idea. It may contain errors. You may need to debug it.)

Hope this can help.

Regards
Peter Kwan