mirror of https://github.com/rusefi/jzy3d-api.git
Adding tests on Angle. Adding Permutations to generate all possible permutations of a set. Adding benchmark tools to prove that big and less polygon render faster than small and more
This commit is contained in:
parent
c89d189b22
commit
06921da699
|
@ -405,6 +405,13 @@ public class Chart {
|
|||
public void remove(Drawable drawable, boolean updateViews) {
|
||||
getScene().getGraph().remove(drawable, updateViews);
|
||||
}
|
||||
|
||||
public void remove(List<? extends Drawable> drawables) {
|
||||
for (Drawable drawable : drawables) {
|
||||
remove(drawable, false);
|
||||
}
|
||||
getView().updateBounds();
|
||||
}
|
||||
|
||||
/* ADDING LIGHTS */
|
||||
|
||||
|
|
|
@ -12,26 +12,19 @@ import java.util.Random;
|
|||
*/
|
||||
public class Color {
|
||||
|
||||
/** Black color. */
|
||||
public static final Color BLACK = new Color(0.0f, 0.0f, 0.0f);
|
||||
/** White color. */
|
||||
public static final Color WHITE = new Color(1.0f, 1.0f, 1.0f);
|
||||
/** Gray color. */
|
||||
public static final Color GRAY = new Color(0.5f, 0.5f, 0.5f);
|
||||
|
||||
/** Red color. */
|
||||
public static final Color RED = new Color(1.0f, 0.0f, 0.0f);
|
||||
/** Green color. */
|
||||
public static final Color GREEN = new Color(0.0f, 1.0f, 0.0f);
|
||||
/** Blue color. */
|
||||
public static final Color BLUE = new Color(0.0f, 0.0f, 1.0f);
|
||||
|
||||
/** Yellow color. */
|
||||
public static final Color YELLOW = new Color(1.0f, 1.0f, 0.0f);
|
||||
/** Magenta color. */
|
||||
public static final Color MAGENTA = new Color(1.0f, 0.0f, 1.0f);
|
||||
/** Cyan color. */
|
||||
public static final Color CYAN = new Color(0.0f, 1.0f, 1.0f);
|
||||
|
||||
public static final Color ORANGE = new Color(1.0f, 165.0f/255.0f, 0);
|
||||
|
||||
public static final Color[] COLORS = {RED, GREEN, BLUE, YELLOW, MAGENTA, CYAN};
|
||||
|
||||
|
|
|
@ -1,10 +1,29 @@
|
|||
package org.jzy3d.maths;
|
||||
|
||||
import java.util.List;
|
||||
import org.jzy3d.plot3d.primitives.Point;
|
||||
|
||||
/**
|
||||
* An Angle3d stores three 3d points, considering the angle is on the second one. An instance may
|
||||
* return angle(), cos() and sin().
|
||||
*/
|
||||
public class Angle3d {
|
||||
public static final double DEGREE_90_D = Math.PI / 2;
|
||||
public static final float DEGREE_90 = (float) DEGREE_90_D;
|
||||
|
||||
public static final double DEGREE_45_D = Math.PI / 4;
|
||||
public static final float DEGREE_45 = (float) DEGREE_45_D;
|
||||
|
||||
protected float x1;
|
||||
protected float x2;
|
||||
protected float x3;
|
||||
protected float y1;
|
||||
protected float y2;
|
||||
protected float y3;
|
||||
protected float z1;
|
||||
protected float z2;
|
||||
protected float z3;
|
||||
|
||||
|
||||
/**
|
||||
* Create an angle, described by three points. The angle is supposed to be on p2
|
||||
|
@ -68,23 +87,96 @@ public class Angle3d {
|
|||
|
||||
/** Computes the angle at vertex p2 between rays p1,p2 and p3,p2. Returns 0 to PI radians. */
|
||||
public float angle() {
|
||||
return (float) angleD();
|
||||
}
|
||||
|
||||
/** Computes the angle at vertex p2 between rays p1,p2 and p3,p2. Returns 0 to PI radians. */
|
||||
public double angleD() {
|
||||
double lenP1P3 = Math.sqrt(Math.pow(x1 - x3, 2) + Math.pow(y1 - y3, 2) + Math.pow(z1 - z3, 2));
|
||||
double lenP1P2 = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2) + Math.pow(z1 - z2, 2));
|
||||
double lenP3P2 = Math.sqrt(Math.pow(x3 - x2, 2) + Math.pow(y3 - y2, 2) + Math.pow(z3 - z2, 2));
|
||||
double numerator = Math.pow(lenP1P2, 2) + Math.pow(lenP3P2, 2) - Math.pow(lenP1P3, 2);
|
||||
double denominator = 2 * lenP1P2 * lenP3P2;
|
||||
return (float) Math.acos(numerator / denominator);
|
||||
return Math.acos(numerator / denominator);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compute the sum of all angles in the input coordinate list.
|
||||
*
|
||||
* If input contains point A, B, C, this method will compute angles ABC, BCA, CAB.
|
||||
*
|
||||
* An error is thrown if there are less than 3 points.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static double angleSum(List<Coord3d> coords) {
|
||||
if(coords.size()<3) {
|
||||
throw new IllegalArgumentException("Can not compute an angle with less than 3 points");
|
||||
}
|
||||
|
||||
Angle3d[] angles = new Angle3d[coords.size()];
|
||||
|
||||
for (int i = 0; i < coords.size()-2; i++) {
|
||||
angles[i] = new Angle3d(coords.get(i), coords.get(i+1), coords.get(i+2));
|
||||
}
|
||||
angles[coords.size()-2] = new Angle3d(coords.get(coords.size()-2), coords.get(coords.size()-1), coords.get(0));
|
||||
angles[coords.size()-1] = new Angle3d(coords.get(coords.size()-1), coords.get(0), coords.get(1));
|
||||
|
||||
/***********************************************************/
|
||||
|
||||
double cumulated = 0;
|
||||
for(Angle3d angle: angles) {
|
||||
cumulated+=angle.angleD();
|
||||
}
|
||||
return cumulated;
|
||||
}
|
||||
|
||||
public static double angleSumFromPoints(List<Point> coords) {
|
||||
if(coords.size()<3) {
|
||||
throw new IllegalArgumentException("Can not compute an angle with less than 3 points");
|
||||
}
|
||||
|
||||
Angle3d[] angles = new Angle3d[coords.size()];
|
||||
|
||||
for (int i = 0; i < coords.size()-2; i++) {
|
||||
angles[i] = new Angle3d(coords.get(i).xyz, coords.get(i+1).xyz, coords.get(i+2).xyz);
|
||||
}
|
||||
angles[coords.size()-2] = new Angle3d(coords.get(coords.size()-2).xyz, coords.get(coords.size()-1).xyz, coords.get(0).xyz);
|
||||
angles[coords.size()-1] = new Angle3d(coords.get(coords.size()-1).xyz, coords.get(0).xyz, coords.get(1).xyz);
|
||||
|
||||
private float x1;
|
||||
private float x2;
|
||||
private float x3;
|
||||
private float y1;
|
||||
private float y2;
|
||||
private float y3;
|
||||
private float z1;
|
||||
private float z2;
|
||||
private float z3;
|
||||
|
||||
double cumulated = 0;
|
||||
for(Angle3d angle: angles) {
|
||||
cumulated+=angle.angleD();
|
||||
}
|
||||
return cumulated;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the expected sum of all angles of a polygon given its number of points.
|
||||
*
|
||||
* The polygon is supposed to not have any edge crossing another edge.
|
||||
*
|
||||
* @param n
|
||||
* @return
|
||||
*/
|
||||
public static double angleSumOfNonIntersectingPolygon(int n) {
|
||||
if(n<3)
|
||||
return 0;
|
||||
else
|
||||
return (n-2)*180;
|
||||
}
|
||||
|
||||
public static double angleSumOfNonIntersectingPolygonRad(int n) {
|
||||
if(n<3)
|
||||
return 0;
|
||||
else
|
||||
return (n-2)*Math.PI;
|
||||
}
|
||||
|
||||
public static boolean angleSumFromPointsOfNonIntersectingPolygon(List<Point> coords) {
|
||||
double diff= Math.abs(angleSumFromPoints(coords)-angleSumOfNonIntersectingPolygonRad(coords.size()));
|
||||
return diff<0.0001;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,10 @@ public class Coord3d implements Serializable {
|
|||
*/
|
||||
private static final long serialVersionUID = -1636927109633279805L;
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
|
||||
public static List<Coord3d> list(int size) {
|
||||
return new ArrayList<Coord3d>(size);
|
||||
}
|
||||
|
@ -254,6 +258,13 @@ public class Coord3d implements Serializable {
|
|||
z /= c2.z;
|
||||
}
|
||||
|
||||
public void divSelf(float value) {
|
||||
x /= value;
|
||||
y /= value;
|
||||
z /= value;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Divise all components of the current Coord by the same value and return the result in a new
|
||||
* Coord3d.
|
||||
|
@ -376,6 +387,7 @@ public class Coord3d implements Serializable {
|
|||
return Math.sqrt(distanceSq(c));
|
||||
}
|
||||
|
||||
/** Compute the square distance between two coordinates. */
|
||||
public double distanceSq(Coord3d c) {
|
||||
return Math.pow(x - c.x, 2) + Math.pow(y - c.y, 2) + Math.pow(z - c.z, 2);
|
||||
}
|
||||
|
@ -434,7 +446,7 @@ public class Coord3d implements Serializable {
|
|||
public final Coord3d interpolateTo(Coord3d v, float f) {
|
||||
return new Coord3d(x + (v.x - x) * f, y + (v.y - y) * f, z + (v.z - z) * f);
|
||||
}
|
||||
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
/** Return a string representation of this coordinate. */
|
||||
|
@ -605,9 +617,4 @@ public class Coord3d implements Serializable {
|
|||
return clone;
|
||||
}
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
public float x;
|
||||
public float y;
|
||||
public float z;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
package org.jzy3d.maths;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Generate all possible permutations of the input list
|
||||
*
|
||||
* May study https://www.quickperm.org/ as an faster alternative.
|
||||
*
|
||||
* @author martin
|
||||
*
|
||||
*/
|
||||
public class Permutations {
|
||||
public static <E> List<List<E>> of(List<E> original) {
|
||||
if (original.isEmpty()) {
|
||||
List<List<E>> result = new ArrayList<>();
|
||||
result.add(new ArrayList<>());
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
E firstElement = original.remove(0);
|
||||
List<List<E>> returnValue = new ArrayList<>();
|
||||
List<List<E>> permutations = of(original);
|
||||
for (List<E> smallerPermutated : permutations) {
|
||||
for (int index = 0; index <= smallerPermutated.size(); index++) {
|
||||
List<E> temp = new ArrayList<>(smallerPermutated);
|
||||
temp.add(index, firstElement);
|
||||
returnValue.add(temp);
|
||||
}
|
||||
}
|
||||
return returnValue;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -34,6 +34,11 @@ public abstract class Geometry extends Wireframeable implements ISingleColorable
|
|||
add(points);
|
||||
}
|
||||
|
||||
public Geometry(List<Point> points) {
|
||||
this();
|
||||
add(points);
|
||||
}
|
||||
|
||||
public Geometry(Color wireframeColor, Point... points) {
|
||||
this(points);
|
||||
setWireframeColor(wireframeColor);
|
||||
|
@ -188,6 +193,13 @@ public abstract class Geometry extends Wireframeable implements ISingleColorable
|
|||
updateBounds();
|
||||
}
|
||||
|
||||
public void add(List<Point> points) {
|
||||
for(Point p: points) {
|
||||
add(p, false);
|
||||
}
|
||||
updateBounds();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void applyGeometryTransform(Transform transform) {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package org.jzy3d.plot3d.primitives;
|
||||
|
||||
import java.util.List;
|
||||
import org.jzy3d.colors.Color;
|
||||
import org.jzy3d.painters.IPainter;
|
||||
|
||||
|
@ -22,6 +23,10 @@ public class Polygon extends Geometry {
|
|||
super(points);
|
||||
}
|
||||
|
||||
public Polygon(List<Point> points) {
|
||||
super(points);
|
||||
}
|
||||
|
||||
public Polygon(Color wire, Point... points) {
|
||||
super(wire, points);
|
||||
}
|
||||
|
|
|
@ -11,7 +11,9 @@ import org.jzy3d.painters.IPainter;
|
|||
import org.jzy3d.plot3d.transform.Transform;
|
||||
|
||||
/**
|
||||
* Experimental 3d object.
|
||||
* A collection of coordinates rendered as dots.
|
||||
*
|
||||
* Warning : dots having a width of 1 may not be visible in case HiDPI is ON.
|
||||
*
|
||||
* @author Martin Pernollet
|
||||
*
|
||||
|
@ -28,17 +30,33 @@ public class Scatter extends Drawable implements ISingleColorable {
|
|||
this(coordinates, Color.BLACK);
|
||||
}
|
||||
|
||||
public Scatter(List<Coord3d> coordinates) {
|
||||
this(coordinates, Color.BLACK);
|
||||
}
|
||||
|
||||
public Scatter(Coord3d[] coordinates, Color rgb) {
|
||||
this(coordinates, rgb, 1.0f);
|
||||
}
|
||||
|
||||
public Scatter(List<Coord3d> coordinates, Color rgb) {
|
||||
this(coordinates, rgb, 1.0f);
|
||||
}
|
||||
|
||||
public Scatter(Coord3d[] coordinates, Color rgb, float width) {
|
||||
bbox = new BoundingBox3d();
|
||||
this();
|
||||
setData(coordinates);
|
||||
setWidth(width);
|
||||
setColor(rgb);
|
||||
}
|
||||
|
||||
public Scatter(List<Coord3d> coordinates, Color rgb, float width) {
|
||||
this();
|
||||
setData(coordinates);
|
||||
setWidth(width);
|
||||
setColor(rgb);
|
||||
}
|
||||
|
||||
|
||||
public Scatter(Coord3ds coords) {
|
||||
this(coords.coordsArray(), coords.colorsArray());
|
||||
}
|
||||
|
|
|
@ -1,10 +1,26 @@
|
|||
package org.jzy3d.plot3d.primitives.axis.layout.renderers;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
import java.util.Locale;
|
||||
|
||||
public class IntegerTickRenderer implements ITickRenderer {
|
||||
public IntegerTickRenderer() {}
|
||||
boolean separator = false;
|
||||
|
||||
public IntegerTickRenderer() {
|
||||
this(false);
|
||||
}
|
||||
|
||||
public IntegerTickRenderer(boolean separator) {
|
||||
this.separator = separator;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public String format(double value) {
|
||||
return "" + (int) value;
|
||||
if(separator)
|
||||
return NumberFormat.getNumberInstance(Locale.US).format((int) value);
|
||||
else
|
||||
return ""+(int) value;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
package org.jzy3d.maths;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.jzy3d.colors.Color;
|
||||
import org.jzy3d.plot3d.primitives.Point;
|
||||
import org.jzy3d.plot3d.primitives.Polygon;
|
||||
|
||||
public class TestAngle3d {
|
||||
@Test
|
||||
public void testAngle90and45_Vertical() {
|
||||
|
||||
// Given on horizontal square
|
||||
Polygon p1 = new Polygon();
|
||||
p1.add(new Point(new Coord3d(0, 0, 0), Color.BLUE)); // P1 left bottom
|
||||
p1.add(new Point(new Coord3d(1, 0, 0), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(1, 1, 0), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(0, 1, 0), Color.BLUE)); // P1 left top
|
||||
|
||||
|
||||
// When computing angle
|
||||
|
||||
Angle3d a1 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(2).xyz);
|
||||
|
||||
|
||||
Angle3d a2 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(3).xyz);
|
||||
|
||||
// Then
|
||||
Assert.assertEquals(Angle3d.DEGREE_90, a1.angle(), 0.0001);
|
||||
Assert.assertEquals(Angle3d.DEGREE_45, a2.angle(), 0.0001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAngle90and45_Horizontal() {
|
||||
|
||||
// Given on horizontal square
|
||||
Polygon p1 = new Polygon();
|
||||
p1.add(new Point(new Coord3d(0, 0, 0), Color.BLUE)); // P1 left bottom
|
||||
p1.add(new Point(new Coord3d(0, 0, 1), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(0, 1, 1), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(0, 1, 0), Color.BLUE)); // P1 left top
|
||||
|
||||
|
||||
// When computing angle
|
||||
|
||||
Angle3d a1 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(2).xyz);
|
||||
|
||||
|
||||
Angle3d a2 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(3).xyz);
|
||||
|
||||
// Then
|
||||
Assert.assertEquals(Angle3d.DEGREE_90, a1.angle(), 0.0001);
|
||||
Assert.assertEquals(Angle3d.DEGREE_45, a2.angle(), 0.0001);
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenSumingAnglesOfPolygon_TriangleIs180_SquareIs360() {
|
||||
// square
|
||||
Coord3d c1 = new Coord3d(0,0,0); // bottom left
|
||||
Coord3d c2 = new Coord3d(1,0,0); // bottom right
|
||||
Coord3d c3 = new Coord3d(1,1,0); // top right
|
||||
Coord3d c4 = new Coord3d(0,1,0);
|
||||
|
||||
Assert.assertEquals(2*Math.PI, Angle3d.angleSum(Coord3d.list(c1,c2,c3,c4)), 0.0001);
|
||||
Assert.assertEquals(Math.PI, Angle3d.angleSum(Coord3d.list(c1,c2,c3)), 0.0001);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void sumOfIncompleteAngles() {
|
||||
Angle3d.angleSum(Coord3d.list(Coord3d.IDENTITY));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void sumOfIncompleteAngles2() {
|
||||
Angle3d.angleSum(Coord3d.list(Coord3d.IDENTITY, Coord3d.IDENTITY));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sumOfAnglesExpect() {
|
||||
Assert.assertEquals(180, Angle3d.angleSumOfNonIntersectingPolygon(3), 0.0001);
|
||||
Assert.assertEquals(360, Angle3d.angleSumOfNonIntersectingPolygon(4), 0.0001);
|
||||
}
|
||||
|
||||
/*@Test
|
||||
public void testAngle90and45_nonPlanar() {
|
||||
|
||||
// Given
|
||||
Polygon p1 = new Polygon();
|
||||
p1.add(new Point(new Coord3d(0, 0, 0), Color.BLUE)); // P1 left bottom
|
||||
p1.add(new Point(new Coord3d(1, 0, 1), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(1, 1, 0), Color.BLUE)); // neighbor edge will be dropped
|
||||
p1.add(new Point(new Coord3d(0, 1, 0), Color.BLUE)); // P1 left top
|
||||
|
||||
|
||||
// When computing angle
|
||||
|
||||
Angle3d a1 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(2).xyz);
|
||||
|
||||
|
||||
Angle3d a2 = new Angle3d(p1.get(0).xyz, p1.get(1).xyz, p1.get(3).xyz);
|
||||
|
||||
// Then
|
||||
Assert.assertEquals(Angle3d.DEGREE_90, a1.angle(), 0.0001);
|
||||
Assert.assertEquals(Angle3d.DEGREE_45, a2.angle(), 0.0001);
|
||||
|
||||
}*/
|
||||
}
|
|
@ -91,4 +91,6 @@ public class TestCoord3d {
|
|||
Assert.assertFalse(new Coord3d(Float.POSITIVE_INFINITY, 2, 3)
|
||||
.equals(new Coord3d(Float.NEGATIVE_INFINITY, 2, 3)));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -45,6 +45,12 @@
|
|||
<artifactId>jzy3d-tester-native</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>jzy3d-io-xls</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
package org.jzy3d.performance.polygons;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.jzy3d.chart.Chart;
|
||||
import org.jzy3d.chart.factories.AWTChartFactory;
|
||||
import org.jzy3d.chart.factories.ChartFactory;
|
||||
import org.jzy3d.colors.Color;
|
||||
import org.jzy3d.io.xls.ExcelBuilder;
|
||||
import org.jzy3d.maths.BoundingBox3d;
|
||||
import org.jzy3d.maths.Coord3d;
|
||||
import org.jzy3d.painters.Font;
|
||||
import org.jzy3d.plot3d.primitives.LineStrip;
|
||||
import org.jzy3d.plot3d.primitives.Scatter;
|
||||
import org.jzy3d.plot3d.primitives.axis.layout.LabelOrientation;
|
||||
import org.jzy3d.plot3d.primitives.axis.layout.renderers.IntegerTickRenderer;
|
||||
import org.jzy3d.plot3d.rendering.canvas.Quality;
|
||||
|
||||
public class BenchmarkPlot implements BenchmarkXLS{
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
|
||||
// -------------------------------
|
||||
// Chart configuration for plotting
|
||||
ChartFactory f = new AWTChartFactory();
|
||||
//ChartFactory f = new EmulGLChartFactory();
|
||||
Quality q = Quality.Advanced();
|
||||
//q.setHiDPI(HiDPI.OFF);
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// Collect benchmark data
|
||||
|
||||
int stepMin = 2; // min number of steps for surface
|
||||
int stepMax = 100; // max number of steps for surface
|
||||
String info = "emulgl-hidpi"; // HiDPI setting during benchmark
|
||||
|
||||
|
||||
String file = BenchmarkUtils.getExcelFilename(outputFolder, stepMin, stepMax, info);
|
||||
ExcelBuilder xls = new ExcelBuilder(file);
|
||||
xls.setCurrentSheet(SHEET_BENCHMARK);
|
||||
|
||||
int line = 0;
|
||||
|
||||
|
||||
List<Coord3d> data = new ArrayList<>();
|
||||
|
||||
Cell cellTime = xls.getCell(line, TIME);
|
||||
Cell cellPoly = xls.getCell(line, POLYGONS);
|
||||
|
||||
double maxX = 0;
|
||||
|
||||
while(cellTime!=null && cellPoly!=null) {
|
||||
double x = cellPoly.getNumericCellValue();
|
||||
double y = cellTime.getNumericCellValue();
|
||||
|
||||
if(x>maxX)
|
||||
maxX = x;
|
||||
|
||||
data.add(new Coord3d(x, y, 0));
|
||||
|
||||
cellTime = xls.getCell(line, TIME);
|
||||
cellPoly = xls.getCell(line, POLYGONS);
|
||||
|
||||
line++;
|
||||
}
|
||||
|
||||
System.out.println("loaded " + line + " XLS lines");
|
||||
|
||||
|
||||
// -------------------------------
|
||||
// Plot benchmark data
|
||||
|
||||
|
||||
|
||||
Chart c = f.newChart(q);
|
||||
|
||||
c.view2d();
|
||||
c.add(new Scatter(data, Color.BLUE, 2));
|
||||
c.add(line(40, maxX, Color.GREEN, 2));
|
||||
c.add(line(60, maxX, Color.ORANGE, 2));
|
||||
c.add(line(80, maxX, Color.RED, 2));
|
||||
c.getAxisLayout().setXAxisLabel("Number of polygons (polygons all together cover the same surface)");
|
||||
c.getAxisLayout().setYAxisLabel("Rendering time (ms)");
|
||||
c.getAxisLayout().setYAxisLabelOrientation(LabelOrientation.PARALLEL_TO_AXIS);
|
||||
c.getAxisLayout().setFont(Font.Helvetica_18);
|
||||
c.getAxisLayout().setXTickRenderer(new IntegerTickRenderer(true));
|
||||
|
||||
c.getView().setBoundManual(new BoundingBox3d(0, (float)maxX, 0, 400, -10, 10));
|
||||
|
||||
c.open(file, 1024, 768);
|
||||
|
||||
|
||||
//DebugGLChart3d debugChart = new DebugGLChart3d(c, new AWTChartFactory());
|
||||
//debugChart.open(new Rectangle(0, 0, 300, 300));
|
||||
|
||||
}
|
||||
|
||||
private static LineStrip line(int ms, double maxX, Color lineColor, int width) {
|
||||
LineStrip line = new LineStrip(lineColor, new Coord3d(0, ms, 0), new Coord3d(maxX, ms, 0));
|
||||
line.setWireframeWidth(width);
|
||||
return line;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,188 @@
|
|||
package org.jzy3d.performance.polygons;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.lang.management.RuntimeMXBean;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import org.jzy3d.chart.Chart;
|
||||
import org.jzy3d.chart.EmulGLSkin;
|
||||
import org.jzy3d.chart.factories.AWTChartFactory;
|
||||
import org.jzy3d.chart.factories.ChartFactory;
|
||||
import org.jzy3d.chart.factories.EmulGLChartFactory;
|
||||
import org.jzy3d.colors.Color;
|
||||
import org.jzy3d.colors.ColorMapper;
|
||||
import org.jzy3d.colors.colormaps.ColorMapRainbow;
|
||||
import org.jzy3d.io.xls.ExcelBuilder;
|
||||
import org.jzy3d.io.xls.ExcelBuilder.Type;
|
||||
import org.jzy3d.maths.Range;
|
||||
import org.jzy3d.maths.Statistics;
|
||||
import org.jzy3d.maths.TicToc;
|
||||
import org.jzy3d.plot3d.builder.Mapper;
|
||||
import org.jzy3d.plot3d.builder.SurfaceBuilder;
|
||||
import org.jzy3d.plot3d.builder.concrete.OrthonormalGrid;
|
||||
import org.jzy3d.plot3d.primitives.Shape;
|
||||
import org.jzy3d.plot3d.rendering.canvas.Quality;
|
||||
import org.jzy3d.plot3d.rendering.view.HiDPI;
|
||||
|
||||
public class BenchmarkRun implements BenchmarkXLS {
|
||||
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
int width = 1024;
|
||||
int height = 768;
|
||||
HiDPI hidpi = HiDPI.ON;
|
||||
boolean alphaEnabled = false;
|
||||
String info = "native"; // for building file name
|
||||
|
||||
boolean offscreen = false;
|
||||
int stepMax = 250; // max number of steps for surface
|
||||
int stepMin = 2; // min number of steps for surface
|
||||
int shoots = 30; // number of trials
|
||||
|
||||
boolean saveImages = false;
|
||||
|
||||
|
||||
ExcelBuilder xls = new ExcelBuilder(Type.XLSX, SHEET_CONFIG);
|
||||
|
||||
RuntimeMXBean runtimeBean = ManagementFactory.getRuntimeMXBean();
|
||||
|
||||
Map<String, String> systemProperties = runtimeBean.getSystemProperties();
|
||||
Set<String> keys = systemProperties.keySet();
|
||||
|
||||
int line = 0;
|
||||
for (String key : keys) {
|
||||
String value = systemProperties.get(key);
|
||||
|
||||
xls.setCell(line, 0, key);
|
||||
xls.setCell(line, 1, value);
|
||||
line++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// --------------------------------------------------------
|
||||
// Configure base quality for standard case
|
||||
|
||||
// ChartFactory factory = new EmulGLChartFactory();
|
||||
ChartFactory factory = new AWTChartFactory();
|
||||
|
||||
if (offscreen)
|
||||
factory.getPainterFactory().setOffscreen(width, height);
|
||||
|
||||
Quality q = Quality.Advanced();
|
||||
q.setAnimated(factory instanceof AWTChartFactory); // RESOLVE ME : CHART DOES NOT SHOW A NON
|
||||
// ANIMATED AWT
|
||||
q.setAlphaActivated(alphaEnabled);
|
||||
q.setHiDPI(hidpi);
|
||||
|
||||
Chart chart = factory.newChart(q);
|
||||
if (!offscreen)
|
||||
chart.open(width, height);
|
||||
|
||||
// EmulGLSkin skin = EmulGLSkin.on(chart);
|
||||
// chart.addMouseCameraController();
|
||||
|
||||
|
||||
Shape surface = null;
|
||||
|
||||
xls.setCurrentSheet(xls.newSheet(SHEET_BENCHMARK));
|
||||
|
||||
|
||||
line = 0;
|
||||
|
||||
|
||||
for (int i = stepMax; i >= stepMin; i--) {
|
||||
|
||||
|
||||
if (surface != null) {
|
||||
chart.remove(surface);
|
||||
chart.render();
|
||||
}
|
||||
|
||||
surface = surface(i);
|
||||
chart.add(surface);
|
||||
|
||||
int polygonNumber = surface.size();
|
||||
|
||||
|
||||
int minPoly = Integer.MAX_VALUE;
|
||||
int maxPoly = 0;
|
||||
|
||||
// Measure perf
|
||||
double[] renderingTime = new double[shoots];
|
||||
|
||||
TicToc t = new TicToc();
|
||||
|
||||
for (int s = 0; s < shoots; s++) {
|
||||
|
||||
t.tic();
|
||||
chart.render();
|
||||
t.toc();
|
||||
|
||||
renderingTime[s] = t.elapsedMilisecond();
|
||||
|
||||
if (renderingTime[s] < 40) {
|
||||
Thread.sleep(50);
|
||||
}
|
||||
|
||||
xls.setCell(line, TIME, renderingTime[s]);
|
||||
xls.setCell(line, POLYGONS, polygonNumber);
|
||||
xls.setCell(line, WIDTH, width);
|
||||
xls.setCell(line, HEIGHT, height);
|
||||
line++;
|
||||
|
||||
if (polygonNumber > maxPoly) {
|
||||
maxPoly = polygonNumber;
|
||||
}
|
||||
if (polygonNumber < minPoly) {
|
||||
minPoly = polygonNumber;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// System.out.println("Median perf for " + n + " polygons : "
|
||||
// + Statistics.median(perf, false) + " after " + shoots + " shoots");
|
||||
// Array.print(perf);
|
||||
|
||||
System.out.println(polygonNumber + ", " + (width * height) + ", "
|
||||
+ Statistics.median(renderingTime, false) + ", " + shoots);
|
||||
|
||||
if (saveImages)
|
||||
chart.screenshot(new File("target/bench-" + polygonNumber + ".png"));
|
||||
|
||||
}
|
||||
|
||||
// finish
|
||||
String file = BenchmarkUtils.getExcelFilename(outputFolder, stepMin, stepMax, info);
|
||||
xls.save(file);
|
||||
|
||||
System.out.println("Wrote " + file + " with " + line + " lines");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static Shape surface(int steps) {
|
||||
SurfaceBuilder builder = new SurfaceBuilder();
|
||||
|
||||
Mapper mapper = new Mapper() {
|
||||
@Override
|
||||
public double f(double x, double y) {
|
||||
return 0;// x * Math.sin(x * y);
|
||||
}
|
||||
};
|
||||
|
||||
Range range = new Range(-3, 3);
|
||||
|
||||
Shape surface = builder.orthonormal(new OrthonormalGrid(range, steps), mapper);
|
||||
|
||||
ColorMapper colorMapper = new ColorMapper(new ColorMapRainbow(), surface);
|
||||
surface.setColorMapper(colorMapper);
|
||||
surface.setFaceDisplayed(true);
|
||||
surface.setWireframeDisplayed(false);
|
||||
surface.setWireframeColor(Color.BLACK);
|
||||
surface.setWireframeWidth(1);
|
||||
return surface;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
package org.jzy3d.performance.polygons;
|
||||
|
||||
public class BenchmarkUtils {
|
||||
public static String getExcelFilename(String outputFolder, int stepMin, int stepMax,
|
||||
String info) {
|
||||
return outputFolder + "/bench-" + stepMin + "-" + stepMax + "-" + info + ".xlsx";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package org.jzy3d.performance.polygons;
|
||||
|
||||
public interface BenchmarkXLS {
|
||||
int TIME = 0;
|
||||
int POLYGONS = 1;
|
||||
int WIDTH = 2;
|
||||
int HEIGHT = 3;
|
||||
|
||||
String SHEET_CONFIG = "config";
|
||||
String SHEET_BENCHMARK = "benchmark";
|
||||
|
||||
String outputFolder = "./data";
|
||||
|
||||
}
|
Loading…
Reference in New Issue