0

this is for homework.

We have to create a JavaFX application, complying to the MVP principle, that shows a static sine-wave, with sliders to control the properties of said sine-wave.

These sliders are the amplitude, frequency, phase, and zoom. They're bound, through the presenter, to properties in my model that make up the sine-wave. These then have listeners to update the model on changes.

For drawing my sine-wave, I chose a polyline and I calculate the X and Y coordinates for each point to a observable list in my model:

for (double x = -360; x < 360; x++) {
    data.add(x);
    data.add(Math.sin(frequency.doubleValue() * x + phase.doubleValue()) * amplitude.doubleValue());
}

Then I reach this dataset to my view through the presenter where I give each point to my polyline:

public void setPoints(ObservableList<Double> list) {
        functionLine.getPoints().clear();
        functionLine.getPoints().addAll(list);
        double temp;
        for(int i = 0;i<functionLine.getPoints().size();i++) {
            //separate x from y coordinates   
            if (i % 2 == 0) {                                          
                temp = functionLine.getPoints().get(i);
                functionLine.getPoints().set(i, temp + (display.getWidth() / 2)); // + displaywidth/2 to get it to the center of the graph
            } else {
                temp = functionLine.getPoints().get(i);
                functionLine.getPoints().set(i, temp + ((display.getHeight() / 2))); //same as above
            }
        }
    }

This also doesn't perform very well because of the for-loop and the interface is laggy, but that's not why I am here. This is what is currently looks like. The polyline and graph (two lines) are located in its own pane:

enter image description here

Now I have tried to also add zoom to this without increasing the width of the actual line, but I can't figure out how to properly scale around the center of my graph. Obviously I have to transform the coordinates of each point, but I don't know how. I have tried several things but it doesn't achieve what I want.

Feels like something I should be able to do on my own, but I can't apparently.

Any help would be appreciated.

Streamline
  • 63
  • 8
  • 1
    There are several `Transform`s available, if you want to be lazy... Make sure to set `privotX` and `pivotY` unless `(0, 0)` is the origin of your coordinate system and the graph... If you don't want to use this, you should be able to do the calculation manually: first translate so that the pivot point of the scale transform becomes `(0,0)`, then scale around the origin and apply the translation inverse to the first, or as formula: `x' = (x - pivotX) * scaleX + pivotX = x * scaleX + pivotX * (1-scaleX)` and `y' = (y - pivotY) * scaleY + pivotY = y * scaleY + pivotY * (1 - scaleY)` – fabian Dec 12 '19 at 20:07
  • BTW: It seems like all the input values could be combined to a single matrix to map points on `y = sin(x)` to the graph coordinates, which could potentially speed up the calculation... – fabian Dec 12 '19 at 20:10
  • Just a hint: The argument of the Math.sin() function has to be given in radians and not degrees. – mipa Dec 12 '19 at 21:45
  • @fabian yes, thank you. This works. Also for the suggestion. Now I just have to optimize a bit. – Streamline Dec 12 '19 at 21:58
  • Related example: [Draw Cartesian plane in JavaFX](https://stackoverflow.com/questions/24005247/draw-cartesian-plane-graphi-with-canvas-in-javafx). Also an interesting related post on [plotting data using the built-in JavaFX charts](https://lankydan.dev/2017/01/29/javafx-graphs-look-pretty-good). – jewelsea Dec 12 '19 at 23:51
  • @jewelsea thanks for the links, but not what I am looking for. The interface you see in the screenshot is an exact replica of the interface that was shown in the details of the exercise. – Streamline Dec 13 '19 at 00:45
  • Oh, I see, the requirement is to look exactly like the screenshot. Still, some of the logic from the Plot class in the first example [Draw Cartesian Plane Graphi with canvas in JavaFX](https://stackoverflow.com/questions/24005247/draw-cartesian-plane-graphi-with-canvas-in-javafx), for example the `mapX` and `mapY` functions might help, but perhaps it is too different than what you need, in which case it is best to just ignore it and find your own solution. – jewelsea Dec 13 '19 at 01:13
  • @jewelsea I have, I created a class Point to store x and y coordinates, which I then store in a ArrayList. Much faster to access this way. I think it's now all working as intended, except for when you zoom out, you run out of x-points and you can see the start and end of the wave. But no important imo. I could create more points, but that tanks the performance again. – Streamline Dec 13 '19 at 01:36

0 Answers0