gotutiyan’s blog

競技プログラミングをやったりopenframeworksでお絵かきをしたりしています。

アステロイド曲線


この前にリサージュ曲線を描きましたが、次はアステロイド曲線です。リサージュ曲線の記事は以下です。
リサージュ曲線 - gotutiyan’s blog


以下のサイトを参考に、リサージュ曲線の式は以下のように表すことができます。圧倒的にわかりやすいですね。

x=a*cos()*cos()*cos();
y=a*sin()*sin()*sin();

もちろん、cosやsinはラジアンの引数を取りますが。
mathtrain.jp


今回はこれを適当に並べてみると、アステロイド曲線を並べているけど円を並べているように見えたので、回転させてみました。面白いですね!

#include "ofApp.h"
#include <vector>
#include <utility>
#include <algorithm>
#define rep(i,j,k) for(int i=j;i<k;i++)
#define pb push_back

class asteroid{
public:
    int n,size;
    double r;
    vector<double> x,y,sita;
    
    void init(int nn,int nsize,double nr){
        n=nn; size=nsize;
        x.resize(n); y.resize(n); sita.resize(n);
        r=nr;
    }
    
    void move(){
        rep(i,0,n){
            sita[i]+=PI/128*(i+1)/n;
            x[i]=size*cos(sita[i])*cos(sita[i])*cos(sita[i]);
            y[i]=size*sin(sita[i])*sin(sita[i])*sin(sita[i]);
            ofDrawCircle(x[i],y[i],r);
        }
    }
};

asteroid a[25];

void ofApp::setup(){
    ofSetRectMode(OF_RECTMODE_CENTER);
    ofSetFrameRate(60);
    ofSetBackgroundColor(0);
    ofSetColor(255);
    ofSetCircleResolution(64);
    //ofNoFill();
    
    rep(i,0,25)a[i].init(50,50,2.0);
}

void ofApp::update(){
    
}

void ofApp::draw(){
    rep(i,0,5)rep(j,0,5){
        ofPushMatrix();
        ofTranslate(50+100*i,50+100*j);
        ofRotate(25*ofGetFrameNum()*DEG_TO_RAD);
        a[i*5+j].move();
        ofPopMatrix();
    }
}