3
\$\begingroup\$

I had seen a YouTube video making actual Lissajous patterns with sand falling from a pendulum with 2 different periods and looking in the Wikipedia page the looked very easy to simulate.

I made a Processing sketch simulating such a pattern. Here is an example output with a = 3, b = 4 (the same as the third Wikipedia example).

enter image description here

// Lissajous patterns simulator
// https://en.wikipedia.org/wiki/Lissajous_curve

void setup() {
  size(600, 600);
  background(255);
}

int A = 300; // X stretching factor
int B = 300; // Y stretching factor
float a = 3; // x "relative importance"
float b = 4; // y "relative importance"
float time = 0; 
int offset = 0;
final float TIMESTEP = 0.001;

void draw() {
  int x = (int) ( A * sin(a*time + offset) );
  int y = (int) ( B * sin(b*time) );

  point(x + A, y + B);
  time += TIMESTEP;
}

I have two main questions:

  1. I kept the names short to match closely the Wikipedia specification, and added a short comment near them. Is this best practice?

  2. I have quite a few related variables. Should I encapsulate them into a class (maybe LissajousSimulator, with a single function updateState)? Or would that just be over-engineering?

\$\endgroup\$
3
\$\begingroup\$

About point (1)
If it's obviously copied from somewhere without changing anything then it's perfectly fine to not change anything to the code itself. Given that you also have the link to the (pseudo-)code. In this case I wouldn't even add comments other than: look at this page to know how it works.

If however you want to integrate it better into your own code to treat it like it's actually part of it then there's no reason to keep the code as close to the original as possible.
Instead you should refactor it until it fits the general java standards. Meaning making variables private, making constants final (static), following naming conventions (both for variables and methods), ...

question (2) (see above if you want to stick to the structure from the source without changing anything. If you start refactoring following coding standards read on)

If like you say there are a number of variables and methods that are forming a coherent group then you should put them into their own class.

For your new class you'll have to find out what to put in the class and what methods to provide.

My first thought is something like this:

public class LissajousPointCalculator{
    private static final int HORIZONTAL_FACTOR = 300;
    private static final int VERTICAL_FACTOR = 300;
    private float xTimeScale;
    private float yTimeScale;
    private float xTimeOffset;

    public LissajousPointCalculator(float xTimeScale, yTimeScale, xTimeOffset){
        this.xTimeScale = xTimeScale;
        this.yTimeScale = yTimeScale;
        this.xTimeOffset = xTimeOffset;
    }

    public Point getPointAt(float time) {
        int x = (int) ( HORIZONTAL_FACTOR  * Math.sin(xTimeScale*time + xTimeOffset) );
        int y = (int) ( VERTICAL_FACTOR  * Math.sin(yTimeScale*time) );

        return new Point(x + HORIZONTAL_FACTOR , y + VERTICAL_FACTOR ); 
    }
}

Note that I did not include any timetracking inside this class. My reasoning is that the other class that uses this one is responsible for deciding which points to draw. So that class is responsible for staring over, deciding the step size, deciding how many points to add before drawing it on the screen etc...

I also made the horizontal and vertical scaling factors constant inside the class. This was just as an example. If you want to be able to change the size of the figure as well it's obvious that you want these as variables that you can pass through constructor or setters instead.

\$\endgroup\$
  • 2
    \$\begingroup\$ As for naming, the original a and b parameters are no kind of 'start'! They are relative time-scales which influence the figure shape – they define how many loops up-and-down and left-and-right the curve makes before it comes back to the starting point. They show up as a number of visible X-maxima and Y-maxima. So they should not be called xStart & yStart, but rather xTimeScale & yTimeScale. \$\endgroup\$ – CiaPan Apr 5 '17 at 9:50
  • \$\begingroup\$ But your class only has one method, should it be just a standalone method? \$\endgroup\$ – Caridorc Apr 5 '17 at 12:20
  • \$\begingroup\$ @CiaPan You are entirely correct and that is also the reason to rename the a and b into something better. Since you understand the code better than I did, you are in a much better position to choose meaningful names. (sorry for just assuming some stuff without actually trying to understand what it did exactly). Perhaps something like xFrequency? Choosing meaningful names is hard :) \$\endgroup\$ – Imus Apr 5 '17 at 14:33
  • 1
    \$\begingroup\$ @kyrill Processing is a programming language closely based on Java, but with added drawing capabilities \$\endgroup\$ – Caridorc Apr 5 '17 at 19:12
  • 1
    \$\begingroup\$ @Imus I tried to replace x/yStart with x/yTimeScale in your answe, as I proposed in the first comment, but my edit has been rejected. If you'd like it to be done you'll need to do it yourself. \$\endgroup\$ – CiaPan Apr 6 '17 at 14:35

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.