... | ... | @@ -20,11 +20,70 @@ The *LineChartRasterizer* currently uses the min and the max of the datasets to |
|
|
There is not much to say about the axis itself, the *LineChartRasterizer* does not use an arrow head to show continuity of the datasets because there is none. It ends with tha max value on the x axis which was present on the dataset. As for the tickmarksize, the *LineChartRasterizer* currently uses 2.
|
|
|
|
|
|
## **Line rasterizing algorithm**
|
|
|
The *LineChartRasterizer* currently uses the **bresenham** algorithm to draw a line between two datapoints as nearly to the ideal line as possible. Because **bresenham** assumes an equal distant grid, there is a conversion to be done between the geometrical position (for example in milimetres) and the dot position, measured in braillecell/ dots. The current implementation looksup the nearest point, which is why there are sometime aritfact points.
|
|
|
The *LineChartRasterizer* currently uses the **bresenham** algorithm to draw a line between two datapoints as nearly to the ideal line as possible. Because **bresenham** assumes an equal distant grid, there is a conversion to be done between the geometrical position (for example in milimetres) and the dot position, measured in braillecell/ dots. The current implementation looksup the nearest point, which is why there are sometime aritfact points.
|
|
|
|
|
|
There is also the issue that on the canvas, the y coordinates grow bigger as they go down, but bresenham assumes that the origin of the y coordinates is in the left bottom corner.
|
|
|
|
|
|
Here the code:
|
|
|
```java
|
|
|
private void bresenham(final Double xStart, final Double yStart, final Double xEnd, final Double yEnd) {
|
|
|
int y0 = (int) (mCanvas.toDotRectangle(mCellLineArea).intWrapper().getHeight() - yStart); // Conversion of the origin
|
|
|
int y1 = (int) (mCanvas.toDotRectangle(mCellLineArea).intWrapper().getHeight() - yEnd); // Conversion of the origin
|
|
|
int x0 = (int) (xStart.doubleValue());
|
|
|
int x1 = (int) (xEnd.doubleValue());
|
|
|
int dx = abs(x1 - x0);
|
|
|
int dy = -abs(y1 - y0);
|
|
|
int sx = x0 < x1 ? 1 : -1;
|
|
|
int sy = y0 < y1 ? 1 : -1;
|
|
|
int err = dx + dy;
|
|
|
int e2;
|
|
|
while (true) {
|
|
|
mCanvas.getCurrentPage().setValue((int) (mCanvas.toDotRectangle(mCellLineArea).getHeight() - y0), (int) x0, true);
|
|
|
if (x0 == x1 && y0 == y1) {
|
|
|
break;
|
|
|
}
|
|
|
e2 = 2 * err;
|
|
|
if (e2 > dy) {
|
|
|
err += dy;
|
|
|
x0 += sx;
|
|
|
}
|
|
|
if (e2 < dx) {
|
|
|
err += dx;
|
|
|
y0 += sy;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
There is future work to be done in evaluating more line draw algorithms, for example "P. Stephenson, B. Litow: Running the line:Line drawing using runs and runs of runs". Sadly, this algorithm is closed source and was only made available after the project finished.
|
|
|
|
|
|
## **Point rasterizing algorithm**
|
|
|
To draw a line, one need a method to draw point. This is also done via a conversion between a geometrical view to a "braille" view.
|
|
|
Here the code:
|
|
|
|
|
|
```java
|
|
|
private SimplePointListImpl rasterizePoints(final PointList list, final double globalMinX, final double globalMinY) {
|
|
|
Objects.requireNonNull(list, "The given PointList for the rasterization of points was null!");
|
|
|
double xMin = globalMinX;
|
|
|
double yMin = globalMinY;
|
|
|
Iterator<Point2DDouble> iter = list.getListIterator();
|
|
|
Rectangle canvas = mCanvas.toDotRectangle(mCellLineArea);
|
|
|
double canvasStartX = canvas.intWrapper().getX();
|
|
|
double canvasStartY = canvas.intWrapper().getBottom();
|
|
|
SimplePointListImpl result = new SimplePointListImpl();
|
|
|
while (iter.hasNext()) { // iterate through all datapoints
|
|
|
Point2DDouble current = iter.next();
|
|
|
double currentValueX = current.getX() - xMin;
|
|
|
double currentValueY = current.getY() - yMin;
|
|
|
double stepX = currentValueX / mDpiX;
|
|
|
double stepY = currentValueY / mDpiY;
|
|
|
result.pushBack(new Point2DDouble(round(canvasStartX + mXStepWidth * mCanvas.getCellWidth() * stepX), round(canvasStartY - mYStepWidth * mCanvas.getCellHeight() * stepY)));
|
|
|
mCanvas.getCurrentPage().setValue((int) round(canvasStartY - mYStepWidth * mCanvas.getCellHeight() * stepY), (int) round(canvasStartX + mXStepWidth * mCanvas.getCellWidth() * stepX), true);
|
|
|
}
|
|
|
result.calculateExtrema();
|
|
|
return result;
|
|
|
}
|
|
|
```
|
|
|
|
|
|
|
|
|
# Testing
|
... | ... | |