Coord3d has more static method to add, sub, mul, div on list of

coordinates. More convenient ImagePanel and ChartGroupWindow.
This commit is contained in:
Martin Pernollet 2017-08-05 17:38:42 +02:00
parent 1be45a5f63
commit 1b8dafb514
10 changed files with 320 additions and 107 deletions

View File

@ -9,7 +9,6 @@ import java.util.Map;
import org.jzy3d.chart.Chart;
import org.jzy3d.colors.Color;
import org.jzy3d.plot2d.primitives.Serie2d;
import org.jzy3d.plot3d.rendering.canvas.IScreenCanvas;
import org.jzy3d.plot3d.rendering.view.modes.ViewBoundMode;
public class Chart2dGroup {

View File

@ -15,30 +15,29 @@ import java.util.List;
* @author Martin Pernollet
*
*/
public class Coord3d implements Serializable{
public class Coord3d implements Serializable {
/**
*
*/
private static final long serialVersionUID = -1636927109633279805L;
public static List<Coord3d> list(int size){
public static List<Coord3d> list(int size) {
return new ArrayList<Coord3d>(size);
}
public static Range getZRange(List<Coord3d> coords) {
float min = Float.POSITIVE_INFINITY;
float max = Float.NEGATIVE_INFINITY;
for(Coord3d c: coords){
if(c.z>max)
for (Coord3d c : coords) {
if (c.z > max)
max = c.z;
if(c.z<min)
min = c.z;
if (c.z < min)
min = c.z;
}
return new Range(min, max);
}
/** The origin is a Coord3d having value 0 for each dimension. */
public static final Coord3d ORIGIN = new Coord3d(0.0f, 0.0f, 0.0f);
/** The origin is a Coord3d having value 1 for each dimension. */
@ -140,7 +139,6 @@ public class Coord3d implements Serializable{
return this;
}
/**
* Add a value to all components of the current Coord and return the result
* in a new Coord3d.
@ -205,11 +203,9 @@ public class Coord3d implements Serializable{
public Coord3d mul(Coord3d c2) {
return new Coord3d(x * c2.x, y * c2.y, z * c2.z);
}
public void mulSelf(Coord3d c2) {
x *= c2.x;
y *= c2.y;
z *= c2.z;
public Coord3d mul(float x, float y, float z) {
return new Coord3d(this.x * x, this.y * y, this.z * z);
}
/**
@ -223,6 +219,12 @@ public class Coord3d implements Serializable{
return new Coord3d(x * value, y * value, z * value);
}
public void mulSelf(Coord3d c2) {
x *= c2.x;
y *= c2.y;
z *= c2.z;
}
/**
* Divise a Coord3d to the current one and return the result in a new
* Coord3d.
@ -259,7 +261,7 @@ public class Coord3d implements Serializable{
* Converts the current Coord3d into cartesian coordinates and return the
* result in a new Coord3d.
*
* Assume that
* Assume that
* <ul>
* <li>X represent azimuth
* <li>Y represent elevation
@ -273,15 +275,13 @@ public class Coord3d implements Serializable{
Math.sin(x) * Math.cos(y) * z, // elevation
Math.sin(y) * z); // range
}
public Coord3d cartesianSelf() {
x = (float)(Math.cos(x) * Math.cos(y) * z); // azimuth
y = (float)(Math.sin(x) * Math.cos(y) * z);// elevation
z = (float)(Math.sin(y) * z); // range
x = (float) (Math.cos(x) * Math.cos(y) * z); // azimuth
y = (float) (Math.sin(x) * Math.cos(y) * z);// elevation
z = (float) (Math.sin(y) * z); // range
return this;
}
/**
* Converts the current Coord3d into polar coordinates and return the result
@ -318,7 +318,7 @@ public class Coord3d implements Serializable{
return new Coord3d(a, e, r);
}
}
public Coord3d polarSelf() {
double a;
double e;
@ -345,9 +345,9 @@ public class Coord3d implements Serializable{
e = Math.atan(z / d);
x = (float)a;
y = (float)e;
z = (float)r;
x = (float) a;
y = (float) e;
z = (float) r;
return this;
}
}
@ -387,22 +387,20 @@ public class Coord3d implements Serializable{
}
public final Coord3d cross(Coord3d v) {
return new Coord3d(
y * v.z - z * v.y,
z * v.x - x * v.z,
x * v.y - y * v.x
);
return new Coord3d(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x);
}
/**
* Applies a rotation represented by the AxisAngle
* notation using the Rodrigues' rotation formula.
* Applies a rotation represented by the AxisAngle notation using the
* Rodrigues' rotation formula.
* <p/>
* math implemented using
* http://en.wikipedia.org/wiki/Rodrigues%27_rotation_formula
*
* @param angleDeg angle of rotation about the given axis [deg]
* @param axis unit vector describing an axis of rotation
* @param angleDeg
* angle of rotation about the given axis [deg]
* @param axis
* unit vector describing an axis of rotation
* @return rotated copy of the original vector
*/
public final Coord3d rotate(float angleDeg, Coord3d axis) {
@ -414,10 +412,7 @@ public class Coord3d implements Serializable{
float kdotv = k.dot(v);
Coord3d kXv = k.cross(v);
return new Coord3d(
v.x * c + kXv.x * s + k.x * kdotv * (1 - c),
v.y * c + kXv.y * s + k.y * kdotv * (1 - c),
v.z * c + kXv.z * s + k.z * kdotv * (1 - c));
return new Coord3d(v.x * c + kXv.x * s + k.x * kdotv * (1 - c), v.y * c + kXv.y * s + k.y * kdotv * (1 - c), v.z * c + kXv.z * s + k.z * kdotv * (1 - c));
}
public final Coord3d interpolateTo(Coord3d v, float f) {
@ -441,28 +436,118 @@ public class Coord3d implements Serializable{
/**************************************************************/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(x);
result = prime * result + Float.floatToIntBits(y);
result = prime * result + Float.floatToIntBits(z);
return result;
}
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + Float.floatToIntBits(x);
result = prime * result + Float.floatToIntBits(y);
result = prime * result + Float.floatToIntBits(z);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Coord3d)) return false;
if (!(obj instanceof Coord3d))
return false;
Coord3d other = (Coord3d) obj;
if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x)) return false;
if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y)) return false;
if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z)) return false;
return true;
}
Coord3d other = (Coord3d) obj;
if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
return false;
if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
return false;
if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
return false;
return true;
}
/**************************************************************/
/**
* Compute the component-wise minimum values of a set of coordinates.
*
* @param coords
* @return minimum value on each dimension
*/
public static Coord3d min(List<Coord3d> coords) {
Coord3d min = new Coord3d(Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
for (Coord3d c : coords) {
if (c.x < min.x)
min.x = c.x;
if (c.y < min.y)
min.y = c.y;
if (c.z < min.z)
min.z = c.z;
}
return min;
}
/**
* Compute the component-wise minimum values of a set of coordinates.
*
* @param coords
* @return maximum value on each dimension
*/
public static Coord3d max(List<Coord3d> coords) {
Coord3d max = new Coord3d(Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
for (Coord3d c : coords) {
if (c.x > max.x)
max.x = c.x;
if (c.y > max.y)
max.y = c.y;
if (c.z > max.z)
max.z = c.z;
}
return max;
}
public static void add(List<Coord3d> coords, float x, float y, float z) {
add(coords, new Coord3d(x, y, z));
}
public static void add(List<Coord3d> coords, Coord3d add) {
for (Coord3d c : coords) {
c.addSelf(add);
}
}
public static void sub(List<Coord3d> coords, float x, float y, float z) {
sub(coords, new Coord3d(x, y, z));
}
public static void sub(List<Coord3d> coords, Coord3d add) {
for (Coord3d c : coords) {
c.subSelf(add);
}
}
public static void mul(List<Coord3d> coords, float x, float y, float z) {
mul(coords, new Coord3d(x, y, z));
}
public static void mul(List<Coord3d> coords, Coord3d multiplier) {
for (Coord3d c : coords) {
c.mulSelf(multiplier);
}
}
public static void div(List<Coord3d> coords, float x, float y, float z) {
div(coords, new Coord3d(x, y, z));
}
public static void div(List<Coord3d> coords, Coord3d div) {
for (Coord3d c : coords) {
c.divSelf(div);
}
}
/**************************************************************/

View File

@ -13,6 +13,7 @@ import org.jzy3d.maths.BoundingBox3d;
import org.jzy3d.maths.Utils;
import org.jzy3d.plot3d.rendering.view.Camera;
import org.jzy3d.plot3d.transform.Transform;
import org.jzy3d.plot3d.transform.space.SpaceTransformer;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.glu.GLU;
@ -118,6 +119,17 @@ public abstract class AbstractComposite extends AbstractWireframeable implements
}
}
}
public void setSpaceTransformer(SpaceTransformer spaceTransformer) {
this.spaceTransformer = spaceTransformer;
synchronized (components) {
for (AbstractDrawable c : components) {
if (c != null)
c.setSpaceTransformer(spaceTransformer);
}
}
}
/** Return the transform that was affected to this composite. */
@Override

View File

@ -517,7 +517,7 @@ public class AxeBox implements IAxe {
}
}
Coord3d tickPosition = new Coord3d(xlab, ylab, zlab);
if (layout.isTickLineDisplayed()) {
if (gl.isGL2()) {
drawTickLine(gl, color, xpos, ypos, zpos, xlab, ylab, zlab);

View File

@ -53,22 +53,28 @@ public interface ICanvas {
/**
* A generic interface for mouse listener to remain Windowing toolkit
* independant. * Implementation of this method should simply cast the input
* assuming it will correspond to canvas-compatible mouse listener.
* independant.
*
* Implementation of this method should simply cast the input assuming it
* will correspond to canvas-compatible mouse listener.
*/
public void addMouseController(Object o);
/**
* A generic interface for mouse listener to remain Windowing toolkit
* independant. * Implementation of this method should simply cast the input
* assuming it will correspond to canvas-compatible mouse listener.
* independant.
*
* Implementation of this method should simply cast the input assuming it
* will correspond to canvas-compatible mouse listener.
*/
public void addKeyController(Object o);
/**
* A generic interface for key listener to remain Windowing toolkit
* independant. * Implementation of this method should simply cast the input
* assuming it will correspond to canvas-compatible key listener.
* independant.
*
* Implementation of this method should simply cast the input assuming it
* will correspond to canvas-compatible key listener.
*/
public void removeMouseController(Object o);

View File

@ -22,6 +22,8 @@ import com.jogamp.opengl.util.gl2.GLUT;
* @author Martin
*/
public class TextBitmapRenderer extends AbstractTextRenderer implements ITextRenderer {
protected static Logger LOGGER = Logger.getLogger(TextBitmapRenderer.class);
/**
* GL Font code and size in pixel to initialize rendeer.
*/
@ -91,10 +93,13 @@ public class TextBitmapRenderer extends AbstractTextRenderer implements ITextRen
posReal = cam.screenToModel(gl, glu, posScreenShifted);
} catch (RuntimeException e) {
// TODO: solve this bug due to a Camera.PERSPECTIVE mode.
Logger.getLogger(TextBitmapRenderer.class).error("TextBitmap.drawText(): could not process text position: " + posScreen + " " + posScreenShifted);
LOGGER.error("TextBitmap.drawText(): could not process text position: " + posScreen + " " + posScreenShifted);
return new BoundingBox3d();
}
//LOGGER.info(text + " @ " + position + " projected to : " + posScreen + " shifted to " + posScreenShifted);
//LOGGER.info(text + " @ " + posReal + " with offset : " + sceneOffset);
// Draws actual string
glRasterPos(gl, sceneOffset, posReal);
glut.glutBitmapString(font, text);

View File

@ -9,7 +9,6 @@ import java.awt.event.MouseWheelListener;
import org.jzy3d.chart.Chart;
import org.jzy3d.chart.controllers.camera.AbstractCameraController;
import org.jzy3d.chart.controllers.mouse.AWTMouseUtilities;
import org.jzy3d.chart.controllers.thread.camera.CameraThreadController;
import org.jzy3d.maths.Coord2d;

View File

@ -0,0 +1,88 @@
package org.jzy3d.plot3d.rendering.view;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;
import javafx.scene.image.Image;
import org.jzy3d.plot3d.rendering.view.AWTRenderer3d;
import org.jzy3d.plot3d.rendering.view.View;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.awt.AWTGLReadBufferUtil;
/** A renderer generating AWT {@link BufferedImage}s and notifying a {@link DisplayListener} when
* it is updated.
*
* @author Martin Pernollet
*/
public class AWTImageRenderer3d extends AWTRenderer3d {
public interface DisplayListener{
public void onDisplay(Object image);
}
protected List<DisplayListener> listeners = new ArrayList<DisplayListener>();
public AWTImageRenderer3d() {
super();
}
public AWTImageRenderer3d(View view, boolean traceGL, boolean debugGL, GLU glu) {
super(view, traceGL, debugGL, glu);
}
@Override
public void display(GLAutoDrawable canvas) {
GL gl = canvas.getGL();
if (view != null) {
view.clear(gl);
view.render(gl, glu);
// Convert as JavaFX Image and notify all listeners
BufferedImage image = makeScreenshotAsBufferedImage(gl);
fireDisplay(image);
if (doScreenshotAtNextDisplay) {
//makeScreenshotAsJavaFXImage(gl);
doScreenshotAtNextDisplay = false;
}
}
}
protected BufferedImage makeScreenshotAsBufferedImage(GL gl) {
AWTGLReadBufferUtil screenshot = makeScreenshot(gl);
return screenshot.readPixelsToBufferedImage(gl, true);
}
private AWTGLReadBufferUtil makeScreenshot(GL gl) {
AWTGLReadBufferUtil screenshot = new AWTGLReadBufferUtil(GLProfile.getGL2GL3(), true);
screenshot.readPixels(gl, true);
image = screenshot.getTextureData();
return screenshot;
}
public AWTImageRenderer3d(View view, boolean traceGL, boolean debugGL) {
super(view, traceGL, debugGL);
}
public void addDisplayListener(DisplayListener listener) {
listeners.add(listener);
}
protected void fireDisplay(Object image) {
for(DisplayListener listener : listeners){
listener.onDisplay(image);
}
}
public AWTImageRenderer3d(View view) {
super(view);
}
}

View File

@ -4,7 +4,7 @@ import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import javax.swing.JFrame;
@ -15,43 +15,46 @@ import org.jzy3d.ui.LookAndFeel;
/** A frame to show a list of charts */
public class ChartGroupWindow extends JFrame {
private static final long serialVersionUID = 7519209038396190502L;
private static final long serialVersionUID = 7519209038396190502L;
public ChartGroupWindow(Collection<? extends Chart> charts) throws IOException {
LookAndFeel.apply();
public ChartGroupWindow(Chart... charts) {
this(Arrays.asList(charts));
}
setGridLayout(charts);
public ChartGroupWindow(Collection<? extends Chart> charts) {
LookAndFeel.apply();
windowExitListener();
this.pack();
setVisible(true);
setBounds(new java.awt.Rectangle(10, 10, 800, 600));
}
setGridLayout(charts);
private void setGridLayout(Collection<? extends Chart> charts) {
setLayout(new GridLayout(charts.size(), 1));
windowExitListener();
this.pack();
setVisible(true);
setBounds(new java.awt.Rectangle(10, 10, 800, 600));
}
for (Chart c : charts) {
addChartToGridLayout(c);
}
}
public void addChartToGridLayout(Chart chart) {
JPanel chartPanel = new JPanel(new BorderLayout());
//Border b = BorderFactory.createLineBorder(java.awt.Color.black);
//chartPanel.setBorder(b);
chartPanel.add((java.awt.Component) chart.getCanvas(),
BorderLayout.CENTER);
add(chartPanel);
}
private void setGridLayout(Collection<? extends Chart> charts) {
setLayout(new GridLayout(charts.size(), 1));
public void windowExitListener() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
ChartGroupWindow.this.dispose();
System.exit(0);
}
});
}
for (Chart c : charts) {
addChartToGridLayout(c);
}
}
public void addChartToGridLayout(Chart chart) {
JPanel chartPanel = new JPanel(new BorderLayout());
// Border b = BorderFactory.createLineBorder(java.awt.Color.black);
// chartPanel.setBorder(b);
chartPanel.add((java.awt.Component) chart.getCanvas(), BorderLayout.CENTER);
add(chartPanel);
}
public void windowExitListener() {
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
ChartGroupWindow.this.dispose();
System.exit(0);
}
});
}
}

View File

@ -8,25 +8,41 @@ import javax.swing.ImageIcon;
import javax.swing.JPanel;
public class ImagePanel extends JPanel {
public static Image getImageByPath(String img) {
return new ImageIcon(img).getImage();
}
public ImagePanel(String img) {
this(new ImageIcon(img).getImage());
this(getImageByPath(img));
}
public ImagePanel(Image img) {
this.img = img;
setImage(img);
setLayout(null);
}
public ImagePanel() {
setLayout(null);
}
public void setImage(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
}
public Image getImage(){
return img;
}
@Override
public void paintComponent(Graphics g) {
g.drawImage(img, 0, 0, null);
}
private Image img;
protected Image img;
private static final long serialVersionUID = 1L;
}