Jogl Push/Pop Matrix not working or I misunderstand - jogl

So I have the following calls in my display. the display method has no calls to any state change methods other than loadIdentity. The display method then calls the following.
gl.glPushMatrix();
gl.glRotated(m_angle, 1.0, 1.0, 0.0);
m_angle += 5;
cubeBySquare(gl,0.2);
gl.glTranslated( 0.5, 0.0 , 0.0 );
cubeByVertex(gl,0.2);
gl.glPopMatrix();
The two methods are shown below - basically one attempts to draw a cube using rotate and translate (cubeBySquare) and the other succeeds in drawing a cube by specifying all of the vertices explicitly (cubeByVertex).
protected void cubeBySquare(GL2 gl,double side)
{
/*
* front - blue
*
* draw the square and leave it where it is on XY plane
*/
gl.glPushMatrix();
gl.glColor3d(0.0,0.0,1.0);
square(gl,side);
gl.glPopMatrix();
/*
* back - green
*
* draw square and push it backwards on the Z axis
*/
gl.glPushMatrix();
gl.glColor3d(0.0,1.0,0.0);
gl.glTranslated( 0.0 , 0.0 , -side);
square(gl,side);
gl.glPopMatrix();
/*
* lhs - cyan
*
* draw square and rotate -90 around Y axis
*/
gl.glPushMatrix();
gl.glColor3d(0.0,1.0,1.0);
gl.glRotated(-90, 0.0, 1.0, 0.0);
square(gl,side);
gl.glPopMatrix();
/*
* rhs - red
*
* draw square, rotate -90 aeound Y axis, translate to rhs on X axis
*/
gl.glPushMatrix();
gl.glColor3d(1.0,0.0,0.0);
gl.glRotated(-90, 0.0, 1.0, 0.0);
gl.glTranslated( side, 0.0 , 0.0 );
square(gl,side);
gl.glPopMatrix();
/*
* top - mauve
*
* draw square, rotate -90 around X axis, translate along Y axis
*/
gl.glPushMatrix();
gl.glColor3d(1.0,0.0,1.0);
gl.glRotated( 90, 1.0, 0.0, 0.0);
gl.glTranslated( 0.0 , side , 0.0 );
square(gl,side);
gl.glPopMatrix();
/*
* bottom - yellow
*
* draw square, rotate -90 around X-axis
*/
gl.glPushMatrix();
gl.glColor3d(1.0,1.0,0.0);
gl.glRotated(-90, 1.0, 0.0, 0.0);
square(gl,side);
gl.glPopMatrix();
}
protected void cubeByVertex(GL2 gl,double side)
{
gl.glBegin(GL_QUADS); // of the color cube
// Front - blue
gl.glColor3d(0.0, 0.0, 1.0);
gl.glVertex3d( 0.0 , 0.0 , 0.0 );
gl.glVertex3d( side, 0.0 , 0.0 );
gl.glVertex3d( side, side, 0.0 );
gl.glVertex3d( 0.0 , side, 0.0 );
// Back - green
gl.glColor3d(0.0, 1.0, 0.0);
gl.glVertex3d( 0.0 , 0.0 , -side);
gl.glVertex3d( side, 0.0 , -side);
gl.glVertex3d( side, side, -side);
gl.glVertex3d( 0.0 , side, -side);
// Left - cyan
gl.glColor3d(0.0, 1.0, 1.0);
gl.glVertex3d( 0.0 , 0.0 , 0.0 );
gl.glVertex3d( 0.0 , 0.0 , -side);
gl.glVertex3d( 0.0 , side, -side);
gl.glVertex3d( 0.0 , side, 0.0 );
// Right - red
gl.glColor3d(1.0, 0.0, 0.0);
gl.glVertex3d( side, 0.0 , 0.0 );
gl.glVertex3d( side, 0.0 , -side);
gl.glVertex3d( side, side, -side);
gl.glVertex3d( side, side, 0.0 );
// Top - mauve
gl.glColor3d(1.0, 0.0, 1.0);
gl.glVertex3d( 0.0 , side, 0.0 );
gl.glVertex3d( side, side, 0.0 );
gl.glVertex3d( side, side, -side);
gl.glVertex3d( 0.0 , side, -side);
// Bottom - yellow
gl.glColor3d(1.0, 1.0, 0.0);
gl.glVertex3d( 0.0 , 0.0 , 0.0 );
gl.glVertex3d( side, 0.0 , 0.0 );
gl.glVertex3d( side, 0.0 , -side);
gl.glVertex3d( 0.0 , 0.0 , -side);
gl.glEnd(); // of the color cube
}
The result is unexpected as you can see in the image. I have tried to see where my logic is wrong but I cannot find any thing unexpected. It looks to me like the push/pop matrix is not really clearing the matrix from the stack. Which probably means I am not using it correctly - yet it looks like most of the examples for hierarchical drawing that I have found on the web.
It seem there is no way to include an image here which make the explanation clumsy.
Basically thr cubeBySquare version rotates and translates all over the shop and not where I expect - thinking previous rotate and translates are affecting the more recent endering even though I have each square bracketed by push/pop matrix

After racking my brains for the last 3 days. Suddenly the light dawned - the order of applying rotation then translation was messing with my head. I forgot the rotation meant that the coordinate system had rotated so after this point the use of absolute coordinates when the frame of reference had rotated meant all sorts of unexpected results - give my incorrect assumption.
Slightly embarrassed but happy to finally understand.

Related

CSS double transition in-out renders strangely

I am trying to render beautiful pages transitions in my react application. I chose simple fade-in/fade-out transitions, and they work perfectly for random pages. But it happens that some pages are quite identical (just a text change), and in that case the transition is not so good (see code-pen bellow for a concrete example).
The way I understand mathematics, if I have two layers, let's say A and B, a linear fade-out of A starting above a similar linear fade-in of B should give constant pixels colors for pixels of the exact same color in both layers, isn't it? But as you can see in that codepen, it's not the case (i was hoping to have no visual effect as the two layers have the exact same color), and I don't understand why. Is there a way to obtain the desired result (for a given pixel, color B replace color A if they are different, but stay still if they are the same)?
https://codepen.io/st-phane-smirnow/pen/dyJaBPG
And here is the corresponding code - HTML:
<div class="a1">a1 div</div>
<div class="a2 hidden">a2 div</div>
<button>Switch divs<button>
CSS:
.a1, .a2 {
display: flex;
justify-content: center;
align-items: center;
position: absolute;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: red;
transition: all .5s linear;
}
.hidden { opacity: 0; }
button {
position: absolute;
top: 10px;
left: 10px;
}
JS:
window.addEventListener("load", () => {
document.querySelector("button").addEventListener("click", () => {
document
.querySelectorAll("div")
.forEach(d => d.classList.toggle("hidden"));
});
});
EDIT: I partially solved my problem by disabling the transparency of the underlying layer. That way, the application background, whatever it is, is hidden by the second layer (opacity always to 1), and the foremost layer just fade-in the underlaying layer. I don't know if, in a perfect world, that result is really different of what I would have got of a truly functional cross-fade, but at least it give a good result at screen.
It's because during the transition, they are both transparent so you're seeing the white background through them.
Here's an interesting post that shows some formulas that might help to why the resulting color isn't rgb(255,0,0) all the way through. Basically, some of the green and blue channel are being introduced.
It's reasonable to think that a 90% red + a 10% red would be a 100% red, but actually each layer is letting a little bit of 'white light' through. Here's how:
According to the post, the general formula for a 2 layer image is:
Y = p*T+(1-p)*B where...
p is the opacity 0...1 of the top layer,
T = rgb number of top layer color,
B is the rgb number of fully opaque bottom layer.
Y is the rgb number of the equivalent fully opaque color. 
So, say you have rgba(255, 0, 0, 0.9) on a white background. The resulting color is:
r = 0.9 * 255 + 0.1 * 255 = 255
g = 0.9 * 0 + 0.1 * 255 = 25.5
b = 0.9 * 0 + 0.1 * 255 = 25.5
Now let's add a rgba(255, 0, 0, 0.1) on top of that result:
r = 0.1 * 255 + 0.9 * 255 = 255
g = 0.1 * 0 + 0.9 * 25.5 = 22.9
b = 0.1 * 0 + 0.9 * 25.5 = 22.9
The extra green and blue channels are moving the color towards white.

QGraphicsItemAnimation: How to indicate rotation point using setRotationAt

When I use QGraphicsItemAnimation::setRotationAt() function to rotate a QGraphicsItem for an animation, the original point is always left top point of the item.
So I tried QGraphicsItem::setTransformOriginPoint() to make the rotation point to be at right top. But it still doesn't work. Is there any way to rotate the item itself at the right top?
for (int i = 0; i < 1000; ++i){
mAnimation->setTranslationAt(i / 1000.0, size.w, 0);
mAnimation->setRotationAt(i / 1000.0, qreal(i / 1000.0 * angle));
mAnimation->setTranslationAt(i / 1000.0, -size.w, 0);
}
Here is the answer i found, when set frames of the item, need to translate the original point before rotation, and translate it back.

QGraphicsView to pdf

I have a big scene successfully displayed in my window with the help of QGraphicsView/QGraphicsScene with scroll bars for navigation. Everything works fine.
Now I would like now to render part of the scene in a pdf. The region to be render in the pdf should be the area visible in the window and the rectangles above and under the visible area.
I've tried that (to begin simply, I've ignored if horizontal scroll bar have been used) :
QPrinter myPrinter(QPrinter::ScreenResolution);
myPrinter.setOrientation(QPrinter::Landscape);
myPrinter.setPaperSize(QPrinter::A4);
myPrinter.setOutputFormat(QPrinter::PdfFormat);
myPrinter.setPageMargins(0.0, 0.0, 0.0, 0.0, QPrinter::Point);
QPainter myPainter(&myPrinter);
m_pageWidth = myPrinter.width();
m_pageHeight = myPrinter.height();
myPainter.setViewport(0, 0, m_pageWidth, m_pageHeight);
QRectF viewRender = QRect(0.0, 0.0, m_pageWidth, m_pageHeight);
for(int i = 0; i < myScene->getNbPages(); i++)
{
QRect viewScene = QRect(0, m_pageHeight * i, m_pageWidth, m_pageHeight);
setSceneRect(viewScene);
render(&myPainter, viewRender, viewScene);
if(i + 1 < myScene->getNbPages())
myPrinter.newPage();
}
But I don't get result as I would expect. For example in this function QGraphicsView::drawBackground(QPainter *painter, const QRectF &rect) rect's top left corner is not at 0, 0 for the first page, but a 107, 98, then at 107, 1585 (but page height is only 793 ?!) and so on...
Anyone understand what is going on ? Thanks for reading.
http://qt-project.org/doc/qt-4.8/qgraphicsview.html#mapToScene
http://qt-project.org/doc/qt-4.8/qgraphicsview.html#mapFromScene
Use one or the other of those appropriately and you should get the results you want.
For example you might try:
render(&myPainter, this->mapToScene(viewRender), viewScene);
// assuming this is your QGraphicsView instance
I demoed how to use this in another question I answered:
How to draw a point (on mouseclick) on a QGraphicsScene?
Hope that helps.

Converting screen point to point on equirectangular texture

I have an equirectangular texture of a panorama that is applied to the inside of a sphere. The camera is placed at the centre of the sphere and the user can rotate the camera to look around by clicking and dragging their mouse. However, when the user clicks and does not drag, I would like to be able to convert the screen co-ordinates to co-ordinates on the texture. I could determine the location on the texture given a the location in the world coordinates the user clicked but looking over the Three.js documentation I am unable to discern how I would go about this.
Ultimately, the question is how would I go about constructing a ray query to get the point of intersection between a ray from a given screen point and the textured sphere?
There are a lot of examples of this in the three.js examples directory. For example, http://mrdoob.github.com/three.js/examples/canvas_interactive_cubes.html.
The pattern your want to google for is this:
var vector = new THREE.Vector3( ( event.clientX / window.innerWidth ) * 2 - 1, - ( event.clientY / window.innerHeight ) * 2 + 1, 0.5 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( objects );
if ( intersects.length > 0 ) {
console.log( intersects[ 0 ].point );
}
This will work if the canvas is full browser. Also, objects is an array.
three.js r.53

upgraded to Flex 3.4 and tried 3.5 PopupManager.centerPopup broken?

How can I center a popup in Flex 3.4+?
In Flex 3.1, I could center a pop-up over its parent by setting its parent in the createPopup, then using centerPopup. In Flex 3.4 and 3.5, the window appears with its upper left corner matching the upper left of its parent... even after the centerPopup.
Is there a work-around? or am I not using centerPopup as intended?
for now, I'm using the following function, stuck into my static WindowUtils class:
// work-around for broken PopupManger.centerPopup in Flex 3.4 and 3.5
public static function centerPopup(popup: UIComponent, centerOn: UIComponent): void
{
var pt:Point = new Point(0, 0);
pt = centerOn.localToGlobal(pt); // Convert local 0,0 into global coordinate
pt = popup.globalToLocal(pt); // Convert the result into local coordinate of myPop
popup.move(Math.round((centerOn.width - popup.width) / 2) + pt.x,
Math.round((centerOn.height - popup.height) / 2) + pt.y);
}

Resources