2013年8月29日木曜日

その場で回転させる ofRotation

ofRectをその場で回転させてみます。


普通にやるとこうなる

/* testApp.m */

static float angle;
static ofVec4f frame;

//--------------------------------------------------------------
void testApp::setup(){ 
 ofxAccelerometer.setup();
    angle = 30;
    frame = ofVec4f(300, 200, 200, 200);
 ofBackground(127,127,127);
}

void testApp::draw0(){
    // 元の位置
    int x = frame.x;
    int y = frame.y;
    int width = frame.z;
    int height = frame.w;
        
    // 普通に描く
    ofSetColor(0, 0, 255);
    ofRect(x, y, width, height);
    ofSetColor(255);
 image.draw(x, y, width, height);
    
    // 座標軸を回転させて描く
    ofPushMatrix();
    ofRotate(angle);
    ofSetColor(0, 255, 0);
    ofRect(x, y, width, height);
    ofPopMatrix();
    
    ofSetColor(255, 255, 255);
    ofCircle(x, y, 10);
    
}

回転させて描画するときは ofRotate で角度を指定してから描画すれば良いのですが、
これだと、座標軸自体が回転してしまうため位置まで変わってしまいます。


回転させた座標軸で元の位置を計算する

その場で回転させるには計算する必要があります。
(x, y)を基準に回転

/* testApp.m */

static float angle;
static ofVec4f frame;

//--------------------------------------------------------------
void testApp::setup(){ 
 ofxAccelerometer.setup();
    angle = 30;
    frame = ofVec4f(300, 200, 200, 200);
 ofBackground(127,127,127);
}

// (x, y)を基準に
void testApp::draw1(){
    // 元の位置
    int x = frame.x;
    int y = frame.y;
    int width = frame.z;
    int height = frame.w;
    
    // 回転させた座標での元の位置
    double radian = (angle) * PI / 180.0;
    double baseRadian = atan2(y, x);
    double dRadian = baseRadian - radian;
    double r = sqrt((x*x) + (y*y)); // powがambiguous
    int newX = cos(dRadian) * r;
    int newY = sin(dRadian) * r;
        
    // 普通に描く
    ofSetColor(0, 0, 255);
    ofRect(x, y, width, height);
    ofSetColor(255);
 image.draw(x, y, width, height);
    
    // 座標軸を回転させて描く
    ofPushMatrix();
    ofRotate(angle);
    ofSetColor(0, 255, 0);
    ofRect(newX, newY, width, height);
    ofPopMatrix();
    
    ofSetColor(255, 255, 255);
    ofCircle(x, y, 10);
    
}

中心点を基準に回転

次は中心点を基準に回転させます

// 中心点(width/2, height/2)を基準に 
void testApp::draw2(){
    int x = frame2.x;
    int y = frame2.y;
    int width = frame2.z;
    int height = frame2.w;
    
    // 中心点
    int posX = frame2.x + width/2.0;
    int posY = frame2.y + height/2.0;
    
    // 回転させた座標での元の位置
    double radian = (angle) * PI / 180.0;
    double baseRadian = atan2(posY, posX);
    double dRadian = baseRadian - radian;
    double r = sqrt((posX*posX) + (posY*posY)); // powがambiguous
    int newPosX = cos(dRadian) * r;
    int newPosY = sin(dRadian) * r;
    int newX = newPosX - width/2.0f;
    int newY = newPosY - height/2.0f;
        
    // 普通に描く
    ofSetColor(0, 0, 255);
    ofRect(x, y, width, height);
    ofSetColor(255);
 image.draw(x, y, width, height);
    
    // 座標軸を回転させて描く
    ofPushMatrix();
    ofRotate(angle);
    ofSetColor(0, 255, 0);
    ofRect(newX, newY, width, height);
    ofSetColor(255, 255, 255);
    ofCircle(newPosX, newPosY, 10);
    ofPopMatrix();
    
}

0 件のコメント:

コメントを投稿