# ofxray projector size

hi

i am using ofxray and created a projector

``````
projector = ofProjector(1024,768);
projector.position = ofVec3f(0,0,10);
projector.aspectRatio = 4.0/3; // 16.0/9; //
//projector.lensOffset = ofVec2f(0,0.5);
projector.throwRatio = 1.0f; //changes the ratio between images size and projection distance
projector.rotation.makeRotate(0,0,1,0);

``````

i am trying to tray rays from the projector to points on the video. see image

even though my track points are at the bottom of the video, they rays are not.
i am mapping the track points to the size of the projector.

``````
outerPoints[n].x = ofMap(convexHull[h].x,0,camW,0,projector.width) ;
outerPoints[n].y = ofMap(convexHull[h].y,0,camH,0,projector.height);

``````

how does the projector size relate to real pixel measurements?

thx.

projector.position = ofVec3f(0,0,10);

when i set the z value back to 0 then the end of the ray does line up with the track points.

but this means as soon as i start moving the projector around the castPixel function does not work any more?

but the question of how the projector pixel measurements relate to let’s say my 320x240 live video, is still unclear to me. right now i am scaling the video by hand to make it fit inside the projector rectangle. scale value is 0.59.

on my journey of understanding ofxRay i learned this:

intersect always returns a value, even when the lines don’t look they intersect.
this can then be used to find the shortest line between two lines in 3D.

``````

void testApp::setup(){
ofBackground(100, 100, 100);
ofEnableSmoothing();
camera.setCursorDraw(true);

ray = ofRay(ofVec3f(0,0,-10),ofVec3f(10,10,0), ofColor(255,0,0),true);
ray1 = ofRay(ofVec3f(2,2,-10),ofVec3f(0,12,0), ofColor(0,0,255),true);

}

//--------------------------------------------------------------
void testApp::update(){

}

//--------------------------------------------------------------
void testApp::draw(){

ofRay testRay = ray.intersect(ray1);
ofRay testRay1 = ray1.intersect(ray);

ofSetColor(255,255,255);
ofDrawBitmapString(ofToString(testRay.s) + "   /   "+ ofToString(testRay.t), 20,20);

//[http://paulbourke.net/geometry/lineline3d/](http://paulbourke.net/geometry/lineline3d/)

camera.begin();
ofSetColor(255,255,255);
ray.draw();
ray1.draw();

ofSetColor(255,255,0);
ofSphere(testRay.s, 0.01);

ofSetColor(255,255,255);
ofSphere(testRay1.s, 0.01);

ofSetColor(0, 0, 0);
ofLine(testRay1.s,testRay.s);

camera.end();
}

//--------------------------------------------------------------
void testApp::keyPressed(int key){

if (key=='1')
ray.s += ofVec3f(-0.1,0,0);
if (key=='2')
ray.s += ofVec3f(0.1,0,0);
if (key=='3')
ray.s += ofVec3f(0,0.1,0);
if (key=='4')
ray.s += ofVec3f(0,-0.1,0);

if (key=='5')
ray.t += ofVec3f(-0.1,0,0);
if (key=='6')
ray.t += ofVec3f(0.1,0,0);
if (key=='7')
ray.t += ofVec3f(0,0.1,0);
if (key=='8')
ray.t += ofVec3f(0,-0.1,0);

if (key=='q')
ray1.s += ofVec3f(-0.1,0,0);
if (key=='w')
ray1.s += ofVec3f(0.1,0,0);
if (key=='e')
ray1.s += ofVec3f(0,0.1,0);
if (key=='d')
ray1.s += ofVec3f(0,-0.1,0);

if (key=='t')
ray1.s += ofVec3f(0,0,-0.1);
if (key=='y')
ray1.s += ofVec3f(0,0,0.1);
if (key=='u')
ray1.t += ofVec3f(0,0,0.1);
if (key=='i')
ray1.t += ofVec3f(0,0,-0.1);

}

``````

-a ray is created from zero origin to point on projector
-this ray intersects plane

``````
//--------------------------------------------------------------
void testApp::setup(){
ofBackground(100, 100, 100);
ofEnableSmoothing();
camera.setCursorDraw(true);

//	ofPlane(ofVec3f center, ofVec3f normal, ofVec3f up, ofVec2f scale);
tria_plane = ofPlane(ofVec3f(0,0,-5),ofVec3f(0,1,1), ofVec3f(0,0,0), ofVec2f(1,1));

projector = ofProjector(1024,768);
projector.position = ofVec3f(0,0,0);
projector.rotation.makeRotate(0,0,0,0);
i = j = 0;

}

//--------------------------------------------------------------
void testApp::update(){

i+=32;
if (i >= projector.width) {
i = 0;
j=j+50;
}
if (j >= projector.height)
j = 0;

pRay = projector.castPixel(i, j);

}

//--------------------------------------------------------------
void testApp::draw(){

camera.begin();

tria_plane.draw();

ofSetColor(0, 0, 0);
projector.draw();

ofSetColor(255, 0, 0);
pRay.draw();

bool intersects;
ofVec3f intersect;
intersects = tria_plane.intersect(pRay, intersect);

ofSetColor(0, 0, 255);
ofCircle(intersect, 0.1);

camera.end();

}

``````

but how do i now rotate the plane in x,y,z ?

i know changing the normal makes it rotate. but i don’t understand the relationship between x,y,z, yet

ofPlane(ofVec3f center, ofVec3f normal, ofVec3f up, ofVec2f scale);
myPlane.setN(ofVec3f(x,y,z));

Hey Stephan!

thanks for giving a really verbose thread here.

ofRay intersection

intersect always returns a value, even when the lines don’t look they intersect.
this can then be used to find the shortest line between two lines in 3D.

A ray is infinitesimally thin (it has no cross section)
Therefore it’s impossible for it to realistically intersect another ray.
So instead, we define an intersection as the ray section between the 2 rays, marking the closest point between the 2 rays.
If you want to check for an intersection, you should measure the length of this ray section, and threshold it.

ofPlane

To better play around with ofPlane and see how it works, i’ve added another example where you can play with the parameters of a plane and see the output.

Also i’ve made changes internally to ofPlane to make drawing more sensible and deal with the up vector better (since the up vector needs to be orthogonal to the normal). The new ofPlane draw function also renders the normal, up and right rays as arrows.

ofPlane rotation

but how do i now rotate the plane in x,y,z ?

i know changing the normal makes it rotate. but i don’t understand the relationship between x,y,z, yet

You’re right, the normal defines the plane’s rotation.
If you want to define it using a transform, then you could do the following:

``````

ofPlane plane;
ofVec3f normal;
ofMatrix4x4 myTransform;
myTransform.makeRotate(90, 1, 0, 0);

plane.setNormal(myTransform * ofVec3f(0,0,1))

``````

So this code presumes you’re imagining that your transform acts on a plane that starts with a normal of

``````
ofVec3f(0,0,1)

``````

you could also do the same for quaternions, using exactly the same code but with ofQuaternion instead of ofMatrix4x4

Furthermore, this could also be applied to the translation of the plane

``````

ofMatrix4x4 myTransform;
..
initialise transform
..
ofVec3f center = ofVec3f(0,0,0) * myTransform;
ofVec3f normal = ofVec3f(0,0,1) * myTransform - center;
ofVec3f up = ofVec3f(0,1,0) * myTransform - center;

``````

when i set the z value back to 0 then the end of the ray does line up with the track points.

but this means as soon as i start moving the projector around the castPixel function does not work any more?

but the question of how the projector pixel measurements relate to let’s say my 320x240 live video, is still unclear to me. right now i am scaling the video by hand to make it fit inside the projector rectangle. scale value is 0.59.

ofProjector is still quite experimental, and doesn’t work at all how i would like it to work.
If setting the position of the projector breaks it, then that must be a bug.
I’ll have a quick look now to see if there’s anything obvious.

hmm… it seems I need to really rewrite ofProjector, but don’t have time right now.
is there a way that you can work around it?

i’m working on some graycode stuff at the moment
once i get past that, i could use ofProjector for something, so could have an excuse to fix it
but maybe another week with all the distractions in the studio at the moment
still useful?

thanks a lot.

ok so there’s an example working with ofProjector now (and ofProjector is remade)
check it out!
i’m not confident that ofMatrix4x4::makePerspectiveMatrix(…) is doing exactly what i expect (it seems about 5% out). might be something to do with near plane interpretation