p5.js 연습 008. 리사주 곡선(Lissajous curve)

written by jjycjn   2017. 7. 21. 05:07

이번에는 리사주 곡선(Lissajous curve)으로 불리는 곡선족을 그려 보았다. 리사주곡선은 다음과 같은 매개변수 방정식으로 나타낼 수 있다.

x=Asin(at+d)y=Bsin(bt)


ab가 서로소이면, 이 두 숫자는 곡선에서 몇 개의 돌출부(lobe)가 있는지를 나타낸다고 한다. 아래 그림에서 a=5이므로, 세로로 다섯개의 돌출부가, b=4이므로 가로로는 네개의 돌출부가 그려짐을 확인할 수 있다. ab가 서로소가 아니면 최대공약수로 약분을 해 주었을 때의 값으로 돌출부의 개수는 판단할 수 있다. 또한 이 곡선을 3차원의 곡선으로 생각할 수 있는데, 이 때, d의 값은 이 곡선을 얼만큼 회전하여 정사영한 모습인지를 나타낸다고 한다.

[각주:1] 슬라이더를 움직인 후에는 꼭 왼쪽 아래에 Refresh 버튼을 눌러야 제대로 된 스파이로그래프를 볼 수 있다.




p5.js 코드 보기

var x, y; 
var t;
var a, b, d;
var Lissajous = [];
var aslider, bslider, dslider, button;

function setup() {
  createCanvas(640, 600);
  
  aslider = createSlider(1, 10, 5, 1);
  aslider.position(20, 20);
  bslider = createSlider(1, 10, 4, 1);
  bslider.position(20, 45);
  dslider = createSlider(0, 1, 0.5, 0.01);
  dslider.position(20, 70);
  button = createButton("Refresh")
    button.position(20, 560);
  button.mousePressed(Refresh);
  t = 0;
}

function draw() {
  background(255);
  
  stroke(220);
  for (var i = 20; i < width; i += 40) {
    line(0, i, width, i);
    line(i, 0, i, height);
  }
  
  a = aslider.value();
  b = bslider.value();
  d = dslider.value();
  x = 200 * sin(a * t + d * PI);
  y = 200 * sin(b * t);
  Lissajous.push(createVector(x,y));
  t += 0.1 / max(abs(a),abs(b));
  
  noStroke();
  fill(0);
  textSize(15);
  text("a = " + a, 28 + aslider.width, 17 + aslider.y);
  text("b = " + b, 28 + bslider.width, 17 + bslider.y);
  text("d = " + d + "PI", 28 + dslider.width, 17 + dslider.y);
  
  translate(width/2 + 20, height/2 + 40);  
  stroke(255, 0, 0);
  noFill();
  beginShape();
  for (var i = 0; i < Lissajous.length; i += 1) {
    vertex(Lissajous[i].x, Lissajous[i].y);
  }
  endShape();
}

function Refresh() {
  background(255);
  Lissajous = [];
  t = 0;
}


  1. 이 때, 회전축은 ab의 값에 따라 달라진다. [본문으로]
  ::  
  • 공유하기  ::