Rotating a Shape Vertically Around the X-Axis

Rotating a shape vertically around the x-axis

Absent a clear question, a simple animation using your coordinate arrays is shown below. In general you can transform the graphics context (g2d) or the polygonal Shape itself (p3); the example shows both. Resize the window to see the effect of each.

Note the last-specified-first-applied order of the transformations in at. First, a suitable point on p3 is translated to the origin, then p3 is scaled, and then p3 is translated to the center of the panel. The + 10 fudge factor applied to p3 is an artifact of having no symmetric rotation point. It may be easier to define your polygons relative to the origin, as shown in this example.

AffineTest

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.AffineTransform;
import javax.swing.*;

/** @see http://stackoverflow.com/questions/3405799 */
public class AffineTest extends JPanel implements ActionListener {

private static final double DELTA_THETA = Math.PI / 45; // 4°
private static final double DELTA_SCALE = 0.1;
private int[] p1x = {200, 200, 240, 240, 220, 220, 200};
private int[] p1y = {200, 260, 260, 240, 240, 200, 200};
private int[] p2x = {600, 600, 620, 620, 640, 640, 660, 660, 600};
private int[] p2y = {400, 420, 420, 460, 460, 420, 420, 400, 400};
private int[] p3x = {400, 400, 460, 460, 440, 440, 420, 420, 400};
private int[] p3y = {400, 460, 460, 400, 400, 440, 440, 400, 400};
private Polygon p1 = new Polygon(p1x, p1y, p1x.length);
private Polygon p2 = new Polygon(p2x, p2y, p2x.length);
private Polygon p3 = new Polygon(p3x, p3y, p3x.length);
private AffineTransform at = new AffineTransform();
private double dt = DELTA_THETA;
private double theta;
private double ds = DELTA_SCALE;
private double scale = 1;
private Timer timer = new Timer(100, this);

public AffineTest() {
this.setPreferredSize(new Dimension(700, 700));
this.setBackground(Color.white);
p1.translate(-50, +100);
p2.translate(-100, -100);
}

@Override
public void actionPerformed(ActionEvent event) {
theta += dt;
scale += ds;
if (scale < .5 || scale > 4) {
ds = -ds;
}
repaint();
}

@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
int w = this.getWidth();
int h = this.getHeight();
g2d.drawLine(w / 2, 0, w / 2, h);
g2d.drawLine(0, h / 2, w, h / 2);
g2d.rotate(theta, w / 2, h / 2);
g2d.drawPolygon(p1);
g2d.drawPolygon(p2);
at.setToIdentity();
at.translate(w / 2, h / 2);
at.scale(scale, scale);
at.translate(-p3x[5] + 10, -p3y[5]);
g2d.setPaint(Color.blue);
g2d.fill(at.createTransformedShape(p3));
}

public void start() {
timer.start();
}

public static void main(String[] args) {
JFrame frame = new JFrame("Affine Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
AffineTest sl = new AffineTest();
frame.add(sl);
frame.pack();
frame.setVisible(true);
sl.start();
}
}

Rotating a polygon around x and y axis

In addition to refactoring and changing magic numbers, consider using a Path2D.Double object instead of a Polygon.

The object's size changes with rotating it around an axis in OpenGL

This looks normal to me.

As you're not using a view matrix, the result of your transform (and thus, the vertex coordinates that you'll see on screen, after projection) will show a triangle that heavily distorts (getting bigger in the Y direction) as it rotates towards you, and the other way around, getting smaller when it rotates away from you.

If you want to make sure your transform is correct, add a view matrix :

glm::mat4 viewMatrix = glm::lookAt(glm::vec3(5.0), glm::vec3(0.0), glm::vec3(0.0, 1.0, 0.0));

You can send it as a uniform to your shader and make it look like this :

gl_Position = projectionMatrix*viewMatrix*rotationMatrix*translationMatrix* vec4(vertexPosition_modelspace,1.0f);

If you can still see the distortion effect, then the problem actually exists, but from your code, my guess is that it's already all working well :)

Rotating and object from left/right and up/down movements

I found a way to make this work. It feels a bit clunky, and I still don't understand why the original method didn't work. If someone has a better solution, I'm still all ears!

This is how I did it:

  • Display the shape in its natural orientation.
  • Every time the user rotates it, add that rotation (using scene axes) to a list of rotations. (Optimise for multiple movements in one direction.)
  • When drawing, apply each of the rotations in turn, in reverse order.

So for example if the user rotates the shape right, up, right, right, down, we store a list:

  • Right = rotate around Y axis 90deg
  • Up = rotate around X axis 90deg
  • Right, Right = rotate around Y axis 180 deg
  • Down = rotate around X axis -90deg

On drawing, glRotatef these in reverse order.

It seems inefficient and I feel there ought to be a better way. I'm sure there is. However it works fine.

Rotate Sphere x Axis Based on Mouse Position in three.js

Possibly, you can achieve the same thing, using THREE.OrbtiControls() with some modifications.

Just an option with moving the camera over the rotating globe.

r96

var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);camera.position.z = 10;var renderer = new THREE.WebGLRenderer();renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);
var globe = new THREE.Mesh(new THREE.SphereGeometry(4, 32, 16), new THREE.MeshBasicMaterial({ map: new THREE.TextureLoader().load("https://c1.staticflickr.com/3/2521/3884071286_edb50f8137_b.jpg")}));scene.add(globe);
window.addEventListener("mousemove", onMouseMove, false);
function onMouseMove(event) { camera.position.setFromSphericalCoords(10, Math.PI * -event.clientY / window.innerHeight, 0); camera.lookAt(globe.position);}
render();
function render() { requestAnimationFrame(render); globe.rotation.y -= 0.005; renderer.render(scene, camera);}
body {  overflow: hidden;  margin: 0;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/96/three.min.js"></script>


Related Topics



Leave a reply



Submit