--- /dev/null
+/**
+ *
+ */
+package de.republib.gui;
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.JPanel;
+
+import de.republib.util.IPairData;
+
+/**
+ * A diagram sheet.
+ *
+ * <pre>
+ * ----------------------------
+ * |<-- vertic. scale
+ * |
+ * |
+ * |
+ * | v-- horiz. scale
+ * |__________________________
+ * -----------------------------
+ * </pre>
+ *
+ * @author hm
+ *
+ */
+public class Diagram extends JPanel {
+ private double realX0 = 0.0;
+ private double realY0 = 0.0;
+ private double realWidth = 1.0;
+ private double realHeight = 1.0;
+ /// 0.0: no fix ration. Otherwise: width / height
+ private final double ratio = 800.0 / 600.0;
+ /// distance horizontal scale to left border
+ private final int hScaleDistance = 5;
+ /// distance vertical scale to bottom
+ private final int vScaleDistance = 5;
+ private final int scaleWidth = 1;
+ private final Color colorScale = Color.DARK_GRAY;
+ private final Color colorScaleFont = Color.BLACK;
+ private final Color colorSheet = Color.WHITE;
+ private final List<IPairData> data = new LinkedList<IPairData>();
+
+ /**
+ * Appends a data package for drawing one line.
+ *
+ * @param data
+ * the pair data for one line
+ * @return the instance (for chaining)
+ */
+ Diagram addData(IPairData data) {
+ this.data.add(data);
+ return this;
+ }
+
+ @Override
+ protected void paintComponent(Graphics graphics) {
+ super.paintComponent(graphics);
+ paintScale(graphics);
+ paintData(graphics);
+ }
+
+ /**
+ * Paints the data as lines in the sheet.
+ *
+ * @param graphics
+ * the graphic environment
+ */
+ protected void paintData(Graphics graphics) {
+ final double x0 = this.realX0;
+ final double realWidth = this.realWidth;
+ final double y0 = this.realY0;
+ final double realHeight = this.realHeight;
+ for (final IPairData data : this.data) {
+ this.realX0 = data.getX(0);
+ this.realWidth = data.getX(data.getSteps() - 1) - this.realX0;
+ int lastX = 0, lastY = 0;
+ for (int ix = 0; ix < data.getSteps(); ix++) {
+ final int x = transformX(data.getX(ix));
+ final int y = transformY(data.getY(ix));
+ if (ix > 0) {
+ graphics.drawLine(lastX, lastY, x, y);
+ }
+ lastX = x;
+ lastY = y;
+ }
+ }
+ this.realX0 = x0;
+ this.realWidth = realWidth;
+ this.realY0 = y0;
+ this.realHeight = realHeight;
+ }
+
+ /**
+ * Paints the scales.
+ *
+ * @param graphics
+ * the graphic environment
+ */
+ protected void paintScale(Graphics graphics) {
+ graphics.setColor(this.colorScale);
+ graphics.drawLine(this.hScaleDistance, this.vScaleDistance, this.getWidth() - this.hScaleDistance,
+ this.vScaleDistance);
+ graphics.drawLine(this.hScaleDistance, this.vScaleDistance, this.hScaleDistance,
+ this.getHeight() - this.vScaleDistance);
+
+ }
+
+ /**
+ * Calculates the x position in pixel from a real x coordinate.
+ *
+ * @param x
+ * the x coordinate in the real world
+ * @return the x value in pixel coordinate
+ */
+ public int transformX(double x) {
+ final double xPixel = (x - this.realX0) * (getWidth() - 2 * this.hScaleDistance);
+ int rc;
+ if (xPixel < 0) {
+ rc = 0;
+ } else if (xPixel > getWidth()) {
+ rc = getWidth();
+ } else {
+ rc = (int) Math.round(xPixel);
+ }
+ return rc;
+ }
+
+ /**
+ * Calculates the y position in pixel from a real y coordinate.
+ *
+ * @param y
+ * the y coordinate in the real world
+ * @return the y value in pixel coordinate
+ */
+ public int transformY(double y) {
+ final double yPixel = (y - this.realY0) * (getHeight() - 2 * this.vScaleDistance);
+ int rc;
+ if (yPixel < 0) {
+ rc = -1;
+ } else if (yPixel > getHeight()) {
+ rc = getHeight();
+ } else {
+ rc = (int) Math.round(yPixel);
+ }
+ return rc;
+ }
+}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import de.republib.pinet.gui.ControlCenter;
+
/**
* A TCP client to use services from a GPIO server.
*/
public class Client {
static Logger logger = LoggerFactory.getLogger(Client.class);
+ public static void client(String host, int port) {
+ final GpioClient client = new GpioClient(host, port);
+ client.blink(PinNumber.PIN_RPi2_12, 10, 500, 500);
+ }
+
+ public static void gui() {
+ final ControlCenter center = new ControlCenter();
+ center.populate();
+ center.run();
+ }
+
/**
* Evaluates the options and start the program.
*
port = Integer.parseInt(arg);
}
}
- final GpioClient client = new GpioClient(host, port);
- client.blink(PinNumber.PIN_RPi2_12, 10, 500, 500);
+ Client.gui();
+ // Client.client(host, port);
}
}
--- /dev/null
+package de.republib.pinet.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.GridLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.JTextField;
+
+import de.republib.gui.Diagram;
+import de.republib.util.I18N;
+
+/**
+ * Created by hm on 03.07.16.
+ */
+public class ControlCenter {
+ private JFrame frame;
+ private JPanel panelCenter;
+ private JPanel panelOutput;
+ private JPanel panelLog;
+ private JLabel labelStatusLine;
+ private JPanel panelData;
+ private JPanel panelHead;
+ private JTextField textFieldServer;
+ private JTextField textFieldPort;
+ private JTabbedPane tabbedPane;
+
+ public void populate() {
+ this.frame = new JFrame(I18N.tr("Pinet Control Center"));
+ this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ this.frame.setMinimumSize(new Dimension(800, 600));
+
+ // Add content to the window.
+ this.frame.add(this.panelCenter = new JPanel(new GridLayout(1, 1)), BorderLayout.CENTER);
+ this.frame.add(this.panelHead = new JPanel(new FlowLayout()), BorderLayout.NORTH);
+ this.frame.add(this.labelStatusLine = new JLabel(I18N.tr("welcome")), BorderLayout.SOUTH);
+
+ this.panelHead.add(new JLabel(I18N.tr("Server:")));
+ this.panelHead.add(this.textFieldServer = new JTextField("localhost"));
+ this.panelHead.add(new JLabel(I18N.tr("Port:")));
+ this.panelHead.add(this.textFieldPort = new JTextField("15000"));
+
+ this.panelCenter.add(this.tabbedPane = new JTabbedPane());
+ this.tabbedPane.addTab(I18N.tr("Output"), this.panelOutput = new JPanel());
+ this.tabbedPane.addTab(I18N.tr("Diagram"), this.panelData = new Diagram());
+ this.tabbedPane.addTab(I18N.tr("Log"), this.panelLog = new JPanel());
+ }
+
+ public void run() {
+ // Display the window.
+ this.frame.pack();
+ this.frame.setVisible(true);
+ }
+}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author hm
+ *
+ */
+public class BytePairData extends DynBytes implements IPairData {
+ static Logger logger = LoggerFactory.getLogger(BytePairData.class);
+ private final double minX;
+
+ private final double maxX;
+
+ private final int dataWidth;
+
+ /**
+ * Constructor.
+ *
+ * @param capacity
+ * @param blocksize
+ * @param minX
+ * @param maxX
+ * @param dataWidth
+ */
+ public BytePairData(int capacity, int blocksize, double minX, double maxX, int dataWidth) {
+ super(capacity, blocksize);
+ if (dataWidth < 0 || dataWidth > 8) {
+ BytePairData.logger.error("getY(): illegal data width: {:d}", dataWidth);
+ dataWidth = 1;
+ }
+ this.minX = minX;
+ this.maxX = maxX;
+ this.dataWidth = dataWidth;
+ }
+
+ /**
+ * @return the dataWidth
+ */
+ public int getDataWidth() {
+ return this.dataWidth;
+ }
+
+ /**
+ * @return the maxX
+ */
+ public double getMaxX() {
+ return this.maxX;
+ }
+
+ /**
+ * @return the minX
+ */
+ public double getMinX() {
+ return this.minX;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IData2D#getSteps()
+ */
+ @Override
+ public int getSteps() {
+ return this.length / this.dataWidth;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IData2D#getX(int)
+ */
+ @Override
+ public double getX(int index) {
+ double x = this.minX;
+ if (index < 0 || index >= this.length / this.dataWidth) {
+ BytePairData.logger.error("getX(): wrong index: {:d} / {:d}", index, this.length / this.dataWidth);
+ } else {
+ x = this.minX + index * (this.maxX - this.minX) / (this.length / this.dataWidth);
+ }
+ return x;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IData2D#getY(int)
+ */
+ @Override
+ public double getY(int index) {
+ double y = 0.0;
+ if (index < 0 || index >= this.length / this.dataWidth) {
+ BytePairData.logger.error("getY(): wrong index: {:d} / {:d}", index, this.length / this.dataWidth);
+ } else {
+ switch (this.dataWidth) {
+ case 1:
+ y = this.buffer[index];
+ break;
+ case 2:
+ case 3:
+ case 4:
+ y = this.intAsLittleEndian(index * this.dataWidth, this.dataWidth, 0);
+ break;
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ y = this.longAsLittleEndian(index * this.dataWidth, this.dataWidth, 0);
+ break;
+ default:
+ BytePairData.logger.error("getY(): illegal data width: {:d}", index, this.dataWidth);
+ break;
+ }
+ }
+ return y;
+ }
+
+}
* @return the instance (for chaining)
*/
public DynBytes appendLittleEndian(int number, int width) {
- if (width >= 1 && width <= 4) {
+ if (width < 1 || width > 4) {
+ DynBytes.logger.debug("appendLitleEndian(%d, %d); wrong width", number, width);
+ } else {
ensureSize(this.length + width);
for (int ix = 0; ix < width; ix++) {
this.buffer[this.length++] = (byte) (number & 0xff);
for (int ii = width - 1; ii >= 0; ii--) {
rc = (rc << 8) | ((this.buffer[index + ii]) & 0xff);
}
+ // first bit == 1?
+ if (width < 4 && rc >> (width * 8 - 1) != 0) {
+ rc = rc - (1 << width * 8);
+ }
}
return rc;
}
for (int ii = width - 1; ii >= 0; ii--) {
rc = (rc << 8) | ((this.buffer[index + ii]) & 0xff);
}
+ // first bit == 1?
+ if (width < 8 && rc >> (width * 8 - 1) != 0) {
+ rc = rc - (1L << width * 8);
+ }
}
return rc;
}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+/**
+ * Generate mathematical functions as (x, y) pairs.
+ *
+ * @author hm
+ *
+ */
+public class FunctionPairData implements IPairData {
+ private final MathFunction function;
+
+ private final double xMin;
+
+ private final double xMax;
+
+ private double factor = 1.0;
+
+ private double factor2 = 1.0;
+
+ private double offset = 0.0;
+
+ private final int steps;
+
+ public FunctionPairData(MathFunction function, double xMin, double xMax, int steps) {
+ this.function = function;
+ this.xMax = xMax;
+ this.xMin = xMin;
+ this.steps = steps;
+ }
+
+ /**
+ * @return the factor
+ */
+ public double getFactor() {
+ return this.factor;
+ }
+
+ /**
+ * @return the factor2
+ */
+ public double getFactor2() {
+ return this.factor2;
+ }
+
+ /**
+ * @return the function
+ */
+ public MathFunction getFunction() {
+ return this.function;
+ }
+
+ /**
+ * @return the offset
+ */
+ public double getOffset() {
+ return this.offset;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IPairData#getCount()
+ */
+ @Override
+ public int getSteps() {
+ return this.steps;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IPairData#getX(int)
+ */
+ @Override
+ public double getX(int index) {
+ return this.xMin + (this.xMax - this.xMin) * index / this.steps;
+ }
+
+ /**
+ * @return the xMax
+ */
+ public double getxMax() {
+ return this.xMax;
+ }
+
+ /**
+ * @return the xMin
+ */
+ public double getxMin() {
+ return this.xMin;
+ }
+
+ /*
+ * (non-Javadoc)
+ *
+ * @see de.republib.util.IPairData#getY(int)
+ */
+ @Override
+ public double getY(int index) {
+ double y = 0.0;
+ final double x = getX(index);
+ switch (this.function) {
+ case COS:
+ y = Math.cos(x);
+ break;
+ case SIN:
+ y = Math.sin(x);
+ break;
+ case TAN:
+ y = Math.tan(x);
+ break;
+ case EXP:
+ y = Math.exp(x);
+ break;
+ case X:
+ y = x;
+ break;
+ case LOG:
+ if (x > 0) {
+ y = Math.log(x);
+ }
+ break;
+ case X2:
+ y = x * x + this.factor2 / this.factor * x;
+ break;
+ default:
+ break;
+ }
+ return y * this.factor + this.offset;
+ }
+
+ /**
+ * @param factor
+ * the factor to set
+ */
+ public void setFactor(double factor) {
+ this.factor = factor;
+ }
+
+ /**
+ * @param factor2
+ * the factor2 to set
+ */
+ public void setFactor2(double factor2) {
+ this.factor2 = factor2;
+ }
+
+ /**
+ * @param offset
+ * the offset to set
+ */
+ public void setOffset(double offset) {
+ this.offset = offset;
+ }
+}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+/**
+ * Internationalization.
+ *
+ * @author hm
+ *
+ */
+public class I18N {
+ /**
+ * Translate a string.
+ *
+ * @param text
+ * text to translate
+ * @return the translated text
+ */
+ public static String tr(final String key) {
+ return key;
+ }
+}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+/**
+ * Interface of a data storage for (x, y) pairs.
+ *
+ * @author hm
+ *
+ */
+public interface IPairData {
+
+ /**
+ * Returns the number of (x, y) pairs.
+ *
+ * @return the number of pairs.
+ */
+ int getSteps();
+
+ /**
+ * Returns the n-th x value.
+ *
+ * @param index
+ * index of the x value: 0..getCount() - 1
+ * @return the <i>index</i>-th x value
+ */
+ double getX(int index);
+
+ /**
+ * Returns the n-th y value.
+ *
+ * @param index
+ * index of the x value: 0..getCount() - 1
+ * @return the <i>index</i>-th x value
+ */
+ double getY(int index);
+}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+/**
+ * @author hm
+ *
+ */
+public enum MathFunction {
+ UNDEF, SIN, COS, TAN, X, X2, EXP, LOG
+}
--- /dev/null
+/**
+ *
+ */
+package de.republib.util;
+
+/**
+ * @author hm
+ *
+ */
+public class PairData {
+ public static double maxY(IPairData data) {
+ double rc = data.getY(0);
+ for (int ix = data.getSteps() - 1; ix > 0; ix--) {
+ final double current = data.getY(ix);
+ if (current > rc) {
+ rc = current;
+ }
+ }
+ return rc;
+ }
+
+ public static double minY(IPairData data) {
+ double rc = data.getY(0);
+ for (int ix = data.getSteps() - 1; ix > 0; ix--) {
+ final double current = data.getY(ix);
+ if (current > rc) {
+ rc = current;
+ }
+ }
+ return rc;
+ }
+}
--- /dev/null
+package de.republib.util;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * Tests the class BytePairData.
+ *
+ * @author hm
+ *
+ */
+public class BytePairDataTest {
+ static Logger logger = LoggerFactory.getLogger(BytePairDataTest.class);
+
+ @Test
+ public void BytePairData() {
+ for (int width = 1; width <= 8; width++) {
+ for (int count = 256; count < width * 256; count++) {
+ testOne(count, width);
+ }
+ }
+ }
+
+ @Test
+ public void getSteps() {
+ testOne(1024, 3);
+ testOne(1024 * 64, 5);
+ testOne(1024 * 128, 8);
+ final BytePairData data = new BytePairData(133, 16, -44.0, 2.55, 2);
+ Assert.assertEquals(data.getLength(), 0);
+
+ Assert.assertEquals(data.getSteps(), 0);
+ Assert.assertEquals(data.getMinX(), -44.0);
+ Assert.assertEquals(data.getMaxX(), 2.55);
+ }
+
+ @Test
+ public void getX() {
+ final BytePairData data = new BytePairData(133, 16, -1000.0, 1000.0, 4);
+ Assert.assertEquals(data.getLength(), 0);
+ for (int ix = 0; ix < 1000; ix++) {
+ data.appendLittleEndian(ix * 314, 4);
+ }
+ Assert.assertEquals(data.getSteps(), 1000);
+ for (int ix = 0; ix < 1000; ix++) {
+ Assert.assertEquals(data.getX(ix), (-1000.0 + ix * 2));
+ Assert.assertEquals(data.getY(ix), 314.0 * ix);
+ }
+ }
+
+ @Test
+ public void getY() {
+ final BytePairData data = new BytePairData(133, 16, -50.0, 50, 8);
+ Assert.assertEquals(data.getLength(), 0);
+ for (int ix = 0; ix < 1000; ix++) {
+ data.appendLittleEndian((long) ix * ix, 8);
+ }
+ Assert.assertEquals(data.getSteps(), 1000);
+ for (int ix = 0; ix < 1000; ix++) {
+ Assert.assertEquals(data.getX(ix), (-50.0 + ix / 10.0));
+ Assert.assertEquals(data.getY(ix), (double) ix * ix);
+ }
+ }
+
+ private void testOne(int count, int dataWidth) {
+ // BytePairDataTest.logger.info(String.format("count: %d width: %d",
+ // count, dataWidth));
+ // capacity should be incremented:
+ final BytePairData data = new BytePairData(count * dataWidth - 16, 16, 0.0, count, dataWidth);
+ for (int ix = 0; ix < count; ix++) {
+ data.appendLittleEndian((long) (ix % 128 - 128), dataWidth);
+ }
+ if (data.getCapacity() < count * dataWidth) {
+ Assert.assertTrue(data.getCapacity() >= count * dataWidth);
+ }
+ Assert.assertEquals(data.getBlocksize(), 16);
+ Assert.assertEquals(data.getLength(), count * dataWidth);
+
+ Assert.assertEquals(data.getSteps(), count);
+ Assert.assertEquals(data.getMinX(), 0.0);
+ Assert.assertEquals(data.getMaxX(), (double) count);
+ Assert.assertEquals(data.getSteps(), count);
+ for (int ix = 0; ix < count; ix++) {
+ Assert.assertEquals(data.getX(ix), (double) ix);
+ Assert.assertEquals(data.getY(ix), (double) (ix % 128 - 128));
+ }
+ }
+}
public void testIntAsLittleEndian() {
final DynBytes buffer = new DynBytes(16, 2);
buffer.appendLittleEndian(0x1234567890abcdefL, 8);
- Assert.assertEquals(buffer.intAsLittleEndian(0, 1, -1), 0xef);
- Assert.assertEquals(buffer.intAsLittleEndian(0, 3, -1), 0xabcdef);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 1, -1), -17 /* 0xef */);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 3, -1), -5517841 /* 0xabcdef */);
Assert.assertEquals(buffer.intAsLittleEndian(1, 4, -1), 0x7890abcd);
Assert.assertEquals(buffer.intAsLittleEndian(6, 2, -1), 0x1234);
// wrong width:
Assert.assertEquals(buffer.intAsLittleEndian(0, 0, -5), -5);
Assert.assertEquals(buffer.intAsLittleEndian(0, 5, -6), -6);
+
+ // negative values:
+ buffer.setLength(0).appendLittleEndian(-128, 1);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 1, -5), -128);
+ buffer.setLength(0).appendLittleEndian(-32000, 2);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 2, -5), -32000);
+ buffer.setLength(0).appendLittleEndian(-1, 3);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 3, -5), -1);
+ buffer.setLength(0).appendLittleEndian(-1, 4);
+ Assert.assertEquals(buffer.intAsLittleEndian(0, 4, -5), -1);
}
@org.testng.annotations.Test
public void testLongAsLittleEndian() {
final DynBytes buffer = new DynBytes(16, 2);
buffer.appendLittleEndian(0x1234567890abcdefL, 8);
- Assert.assertEquals(buffer.longAsLittleEndian(0, 1, -1), 0xefL);
- Assert.assertEquals(buffer.longAsLittleEndian(0, 3, -1), 0xabcdefL);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 1, -1), -17L /* 0xef */);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 3, -1), -5517841L /* 0xabcdef */);
Assert.assertEquals(buffer.longAsLittleEndian(1, 4, -1), 0x7890abcdL);
Assert.assertEquals(buffer.longAsLittleEndian(6, 2, -1), 0x1234L);
// wrong width:
Assert.assertEquals(buffer.intAsLittleEndian(0, 0, -5), -5);
Assert.assertEquals(buffer.intAsLittleEndian(0, 5, -6), -6);
+
+ // negative values:
+ for (int width = 1; width <= 8; width++) {
+ buffer.setLength(0).appendLittleEndian(-1L, width);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, width, -5), -1);
+ buffer.setLength(0).appendLittleEndian(-128L, width);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, width, -5), -128L);
+ }
+ buffer.setLength(0).appendLittleEndian(-128, 1);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 1, -5), -128);
+ buffer.setLength(0).appendLittleEndian(-32000, 2);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 2, -5), -32000);
+ buffer.setLength(0).appendLittleEndian(-1, 3);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 3, -5), -1);
+ buffer.setLength(0).appendLittleEndian(-1, 4);
+ Assert.assertEquals(buffer.longAsLittleEndian(0, 4, -5), -1);
}
@org.testng.annotations.Test
--- /dev/null
+package de.republib.util;
+
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+public class FunctionPairDataTest {
+
+ void checkFunctionCos() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.COS, 0.0, 4 * Math.PI / 4, 4);
+ data.setFactor(2);
+ data.setOffset(-15);
+ Assert.assertEquals(data.getSteps(), 4);
+ Assert.assertEquals(data.getY(0), -15.0 + 2 * Math.cos(0.0));
+ Assert.assertEquals(data.getY(1), -15 + 2 * Math.cos(Math.PI / 4));
+ Assert.assertEquals(data.getY(2), -15 + 2 * Math.cos(Math.PI / 2));
+ Assert.assertEquals(data.getY(3), -15 + 2 * Math.cos(3 * Math.PI / 4));
+ }
+
+ void checkFunctionExp() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.EXP, 0.0, 4.0, 4);
+ data.setFactor(10);
+ data.setOffset(3);
+ Assert.assertEquals(data.getSteps(), 4);
+ Assert.assertEquals(data.getY(0), 13.0);
+ Assert.assertEquals(data.getY(1), 3 + 10 * Math.exp(1.0));
+ Assert.assertEquals(data.getY(2), 3 + 10 * Math.exp(2.0));
+ Assert.assertEquals(data.getY(3), 3 + 10 * Math.exp(3.0));
+ }
+
+ void checkFunctionLog() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.LOG, 1.0, 5.0, 4);
+ data.setFactor(7);
+ data.setOffset(5);
+ Assert.assertEquals(data.getSteps(), 4);
+ Assert.assertEquals(data.getY(0), 5.0 + 7 * Math.log(1));
+ Assert.assertEquals(data.getY(1), 5.0 + 7 * Math.log(2.0));
+ Assert.assertEquals(data.getY(2), 5.0 + 7 * Math.log(3.0));
+ Assert.assertEquals(data.getY(3), 5.0 + 7 * Math.log(4.0));
+ }
+
+ void checkFunctionSin() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.SIN, 0.0, 4 * Math.PI / 4, 4);
+ data.setFactor(2);
+ data.setOffset(-15);
+ Assert.assertEquals(data.getSteps(), 4);
+ Assert.assertEquals(data.getY(0), -15.0);
+ Assert.assertEquals(data.getY(1), -15 + 2 * Math.sin(Math.PI / 4));
+ Assert.assertEquals(data.getY(2), -15 + 2 * Math.sin(Math.PI / 2));
+ Assert.assertEquals(data.getY(3), -15 + 2 * Math.sin(3 * Math.PI / 4));
+ }
+
+ void checkFunctionTan() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.TAN, 0.0, 4 * Math.PI / 4, 4);
+ data.setFactor(2);
+ data.setOffset(-3);
+ Assert.assertEquals(data.getSteps(), 4);
+ Assert.assertEquals(data.getY(0), -3.0);
+ Assert.assertEquals(data.getY(1), -3 + 2 * Math.tan(Math.PI / 4));
+ Assert.assertEquals(data.getY(2), -3 + 2 * Math.tan(Math.PI / 2));
+ Assert.assertEquals(data.getY(3), -3 + 2 * Math.tan(3 * Math.PI / 4));
+ }
+
+ void checkFunctionX() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.X, 0.0, 100.0, 10);
+ data.setFactor(2.0);
+ data.setOffset(-5.0);
+ Assert.assertEquals(data.getSteps(), 10);
+ Assert.assertEquals(data.getY(0), -5.0);
+ Assert.assertEquals(data.getY(9), -5.0 + (100.0 - 10) * 2);
+ }
+
+ void checkFunctionX2() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.X2, 0.0, 2.0, 2);
+ data.setFactor(0.5);
+ data.setFactor2(3.0);
+ data.setOffset(-10.0);
+ Assert.assertEquals(data.getSteps(), 2);
+ Assert.assertEquals(data.getY(0), -10.0);
+ Assert.assertEquals(data.getY(2), -10.0 + 0.5 * 2.0 * 2.0 + 2.0 * 3);
+ }
+
+ @Test
+ public void FunctionPairData() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.X, 0.0, 100.0, 10);
+ Assert.assertEquals(data.getSteps(), 10);
+ }
+
+ @Test
+ public void getSteps() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.X2, 0.0, 100.0, 432);
+ Assert.assertEquals(data.getSteps(), 432);
+ }
+
+ @Test
+ public void getX() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.SIN, 0.0, 100.0, 432);
+ Assert.assertEquals(data.getSteps(), 432);
+ }
+
+ @Test
+ public void getY() {
+ checkFunctionX();
+ checkFunctionX2();
+ checkFunctionSin();
+ checkFunctionCos();
+ checkFunctionTan();
+ checkFunctionExp();
+ checkFunctionLog();
+ }
+
+ @Test
+ public void setFactor() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.SIN, 0.0, 100.0, 432);
+ data.setFactor(44.33);
+ Assert.assertEquals(data.getFactor(), 44.33);
+ }
+
+ @Test
+ public void setFactor2() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.SIN, 0.0, 100.0, 432);
+ data.setFactor2(88.33);
+ Assert.assertEquals(data.getFactor2(), 88.33);
+ }
+
+ @Test
+ public void setOffset() {
+ final FunctionPairData data = new FunctionPairData(MathFunction.SIN, 0.0, 100.0, 432);
+ data.setOffset(-32.44);
+ Assert.assertEquals(data.getOffset(), -32.44);
+ }
+}