As stated in the title: I want to create a 3D cog with 10 teeth which rotates around its center (like a cog does). The cog has square teeth and, for the sake of simplicity, has flat sides between the teeth - no curves on this cog.
Visualization of what one side of the cog should look like. Note that angles are not 100% perfect.
As per the image above, every single cog tooth would have to be an 8 sided polygon, while every single side between the teeth would have to just be a 4 sided polygon. Right now, however, the tooth drawing does the following:
- The side tooth which should be facing the camera is rotated into the floor despite no initial rotation being applied.
- The tooth is twice as wide as it is tall although scaling and vertex creation is done with uniform numbers (it is scaled by
s
in the x, y, z directions and uses either0
or0.5
as vertex coords).
Fully reproducible example:
import java.awt.Dimension;
import javax.swing.JFrame;
import com.jogamp.opengl.GL;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.awt.GLJPanel;
import com.jogamp.opengl.glu.GLU;
import com.jogamp.opengl.util.FPSAnimator;
public class SpinCog3D implements GLEventListener {
JFrame jf;
GLJPanel gljpanel;
Dimension dim = new Dimension(800, 600);
FPSAnimator animator;
float rotation;
float speed;
// set up the OpenGL Panel within a JFrame
public SpinCog3D() {
jf = new JFrame();
gljpanel = new GLJPanel();
gljpanel.addGLEventListener(this);
gljpanel.requestFocusInWindow();
jf.getContentPane().add(gljpanel);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.setVisible(true);
jf.setPreferredSize(dim);
jf.pack();
animator = new FPSAnimator(gljpanel, 20);
rotation = 0.0f;
speed = 0.1f;
animator.start();
}
public static void main(String[] args) {
new SpinCog3D();
}
public void init(GLAutoDrawable dr) {
GL2 gl2 = dr.getGL().getGL2();
GLU glu = new GLU();
gl2.glClearColor(1.0f, 1.0f, 1.0f, 0.0f);
gl2.glEnable(GL2.GL_DEPTH_TEST);
gl2.glMatrixMode(GL2.GL_PROJECTION);
gl2.glLoadIdentity();
glu.gluPerspective(60.0, 1.0, 100.0, 800.0);
}
public void display(GLAutoDrawable dr) {
GL2 gl2 = dr.getGL().getGL2();
GLU glu = new GLU();
gl2.glMatrixMode(GL2.GL_MODELVIEW);
gl2.glLoadIdentity();
glu.gluLookAt(0.0, 200.0, 500.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
gl2.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
// Draw 1 Cog Tooth + 1 Side
drawTooth(gl2, 100.0, 1.0f, 0.0f, 0.0f, 0.0, 0.0, 1.0, 0.0, 0);
drawSide(gl2, 100.0, 0.0f, 1.0f, 0.0f, 0.0, 0.0, 1.0, 0.0, 10);
// Draw Floor
sideRotatedColorScaledFloor(gl2, 300.0, 0.0f, 0.0f, 0.0f, 90.0, 1.0, 0.0, 0.0, 0.0);
gl2.glFlush();
rotation += speed;
if (rotation > 360.9f)
rotation = 0.0f;
}
// draw a single side with a set color and orientation
private void drawTooth(GL2 gl2, double s, float r, float g, float b, double a, double ax, double ay,
double az, double zoffset) {
gl2.glPushMatrix();
gl2.glRotated(a, ax, ay, az);
gl2.glColor3f(r, g, b);
gl2.glTranslated(0.0, 0.0, zoffset);
gl2.glScaled(s, s, s);
tooth(gl2);
gl2.glPopMatrix();
}
private void drawSide(GL2 gl2, double s, float r, float g, float b, double a, double ax, double ay,
double az, double zoffset) {
gl2.glPushMatrix();
gl2.glRotated(a, ax, ay, az);
gl2.glColor3f(r, g, b);
gl2.glTranslated(0.0, 0.0, zoffset);
gl2.glScaled(s, s, s);
side(gl2);
gl2.glPopMatrix();
}
private void sideRotatedColorScaledFloor(GL2 gl2, double s, float r, float g, float b, double a, double ax, double ay,
double az, double zoffset) {
gl2.glPushMatrix();
gl2.glRotated(a, ax, ay, az);
gl2.glColor3f(r, g, b);
gl2.glTranslated(0.0, 0.0, zoffset);
gl2.glScaled(s, s, s);
side(gl2);
gl2.glPopMatrix();
}
private void tooth(GL2 gl2) {
gl2.glBegin(GL2.GL_POLYGON);
gl2.glVertex3d(-0.5, -0.5, 0.0);
gl2.glVertex3d(-0.5, 0.5, 0.0);
gl2.glVertex3d(0.5, 0.5, 0.0);
gl2.glVertex3d(0.5, -0.5, 0.0);
gl2.glVertex3d(-0.5, -0.5, 0.5);
gl2.glVertex3d(-0.5, 0.5, 0.5);
gl2.glVertex3d(0.5, 0.5, 0.5);
gl2.glVertex3d(0.5, -0.5, 0.5);
gl2.glEnd();
}
private void side(GL2 gl2) {
gl2.glBegin(GL2.GL_POLYGON);
gl2.glVertex3d(-0.5, -0.5, 0.0);
gl2.glVertex3d(-0.5, 0.5, 0.0);
gl2.glVertex3d(0.5, 0.5, 0.0);
gl2.glVertex3d(0.5, -0.5, 0.0);
gl2.glEnd();
}
}
Yes I am aware the glBegin()
and glEnd()
has been deprecated since forever, but that's not the point. How do I get my teeth to draw properly and have it aligned with the sides properly?