how to draw a heavy coiled spring?

Hi,

Can someone kindly show me how to draw a heavy coiled spring (like a broken donut spiraled)? I know how to draw a light coiled spring, which is basically a coiled line. Hopefully I don’t have to tessellate it unless it’s the only resort. Any help is much appreciated.

Tony

Try Linas Vesptas’ GLE Tubing & Extrusion Library .

You have to tesselate it.

You need to sweep a circle around a helix.

  1. Generate the points for a circle.
  2. Translate this out along an axis.
  3. Rotate about the origin some parameterized amount.
  4. Translate upwards by some small parameterized amount.
  5. Increase parameterized amount and goto 1

This will points which you then either render or mexh.

You can render as you go but it ain’t essential.

Here’s some code I wrote to draw a torus, copy it and add a translation (stage 4 above). It also has tangent & binormals & other stuff which you probably don’t need.

I just ripped it out of an old project I had with some editing but it should be very close to useable in your program.

#define MINOR_DIV 32
#define MAJOR_DIV 48
#define RadiusMajor 23.0f
#define RadiusMinor 6.0f
#define RepeatsMajor 10.0f
#define RepeatsMinor 4.0f
void DrawTorus(float lod_bias, int numpasses, int pass)
{
	float minor_x, minor_z;
	double major_inc, minor_inc;
	double r_minor, r_major;
	double sin_major1, cos_major1, sin_major2, cos_major2;
	float deltas, deltat;

	static float vert[6*(MAJOR_DIV)*(MINOR_DIV+1)];
	static float norm[6*(MAJOR_DIV+2)*(MINOR_DIV+1)];
	int vert_pos = 0;
	static float tex[4*(MAJOR_DIV)*(MINOR_DIV+1)];
	
	int tex_pos = 0;
	static float tangent[8*(MAJOR_DIV)*(MINOR_DIV+1)];
	static float binorm[8*(MAJOR_DIV)*(MINOR_DIV+1)];
	int tangent_pos = 0;
	int maj_pos, min_pos;
	static int first = 1;
	float tex_shift[4*(MAJOR_DIV)*(MINOR_DIV+1)];
	float brightness = 1.0f/numpasses;
	float VdotN, VprojB, VprojT;
	float tmp_vec[3];
	float pass_mult;
	float Ts, Bs;


	major_inc = M_PI*2/MAJOR_DIV;
	minor_inc = M_PI*2/MINOR_DIV;


	if(first)
	{
		first = 0;
		for (r_major = 0.0f; r_major <= M_PI*2.0-.000001; r_major += major_inc)
		{
			sin_major1 = sin(r_major);
			cos_major1 = cos(r_major);
			sin_major2 = sin(r_major+major_inc);
			cos_major2 = cos(r_major+major_inc);

			for(r_minor = 0.0f; r_minor < M_PI*2.0+.000001; r_minor += minor_inc)
			{
				minor_x = RadiusMinor*(float)sin(r_minor);
				minor_z = RadiusMinor*(float)cos(r_minor);

				tex[tex_pos++] = (RepeatsMajor/2.0f) * (float)(r_major/M_PI);
				tex[tex_pos++] = 0.5f + (RepeatsMinor/2.0f) * (float)(r_minor/M_PI);

				tangent[tangent_pos++] = 0.0f;
				tangent[tangent_pos++] = (float)-cos_major1;
				tangent[tangent_pos++] = (float)sin_major1;
				// texture repeats per unit = repeats / Pi*diameter
				binorm[tangent_pos] = RepeatsMinor / ((float)M_PI * (RadiusMinor + RadiusMinor));
				tangent[tangent_pos++] = RepeatsMajor / ((float)-M_PI * ((minor_z-RadiusMajor) + (minor_z-RadiusMajor)));

				Normalize(tangent+tangent_pos-4);

				norm[vert_pos] = minor_x;
				vert[vert_pos++] = minor_x;
				norm[vert_pos] = (float)sin_major1*minor_z;
				vert[vert_pos++] = (float)sin_major1*(minor_z-RadiusMajor);
				norm[vert_pos] = (float)cos_major1*minor_z;
				vert[vert_pos++] = (float)cos_major1*(minor_z-RadiusMajor);
				Normalize(norm+vert_pos-3);
				
				Cross(binorm+tangent_pos-4, norm+vert_pos-3, tangent+tangent_pos-4);

				tex[tex_pos++] = (RepeatsMajor/2.0f) * (float)((r_major+major_inc)/M_PI);
				tex[tex_pos++] = 0.5f + (RepeatsMinor/2.0f) * (float)(r_minor/M_PI);

				tangent[tangent_pos++] = 0.0f;
				tangent[tangent_pos++] = (float)-cos_major2;
				tangent[tangent_pos++] = (float)sin_major2;
				// texture repeats per unit = repeats / Pi*diameter
				binorm[tangent_pos] = RepeatsMinor / ((float)M_PI * (RadiusMinor + RadiusMinor));
				tangent[tangent_pos++] = RepeatsMajor / ((float)-M_PI * ((minor_z-RadiusMajor) + (minor_z-RadiusMajor)));

				Normalize(tangent+tangent_pos-4);

				norm[vert_pos] = minor_x;
				vert[vert_pos++] = minor_x;
				norm[vert_pos] = (float)sin_major2*minor_z;
				vert[vert_pos++] = (float)sin_major2*(minor_z-RadiusMajor);
				norm[vert_pos] = (float)cos_major2*minor_z;
				vert[vert_pos++] = (float)cos_major2*(minor_z-RadiusMajor);
				Normalize(norm+vert_pos-3);
				
				Cross(binorm+tangent_pos-4, norm+vert_pos-3, tangent+tangent_pos-4);

			}

		}
	}


	glEnable(GL_TEXTURE_2D);

	if(wireframe)
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

    vert_pos = 0;
	for(maj_pos = 0; maj_pos < MAJOR_DIV; maj_pos++)
	{
		glBegin(GL_TRIANGLE_STRIP);
		for(min_pos = 0; min_pos <= MINOR_DIV; min_pos++)
		{
			glTexCoord2f(tex_shift[vert_pos*4], tex_shift[vert_pos*4+1]);
			glNormal3f(norm[vert_pos*6], norm[vert_pos*6+1], norm[vert_pos*6+2]);
			glVertex3f(vert[vert_pos*6], vert[vert_pos*6+1], vert[vert_pos*6+2]);

			glTexCoord2f(tex_shift[vert_pos*4+2], tex_shift[vert_pos*4+3]);
			glNormal3f(norm[vert_pos*6+3], norm[vert_pos*6+4], norm[vert_pos*6+5]);
			glVertex3f(vert[vert_pos*6+3], vert[vert_pos*6+4], vert[vert_pos*6+5]);
			
			vert_pos ++;
		}
		glEnd();
	}

	if(wireframe)
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

	glDisable(GL_TEXTURE_2D);


	if(hedgehog && pass == numpasses)
	{
		// draws normal, tangent and binormal vectors
		// different sides of mesh get drawn two shades with displacement
		// this is to verify matching normals on adjacent meshes
		vert_pos = 0;
		for(maj_pos = 0; maj_pos < MAJOR_DIV; maj_pos++)
		{
			glBegin(GL_LINES);
			for(min_pos = 0; min_pos <= MINOR_DIV; min_pos++)
			{
				// Ts & Bs can be used scale the coordinate frame to texture space,
				// scale is stored in 4th component
				Ts = 1.0f;// /tangent[vert_pos*8+3];
				Bs = 1.0f;// /binorm[vert_pos*8+3];

				// normal
				glColor3f(0.5, 0.0, 0.0);
				glVertex3f(vert[vert_pos*6], vert[vert_pos*6+1], vert[vert_pos*6+2]);
				glVertex3f(vert[vert_pos*6]+norm[vert_pos*6]*.5f, vert[vert_pos*6+1]+norm[vert_pos*6+1]*.5f, vert[vert_pos*6+2]+norm[vert_pos*6+2]*.5f);

				glColor3f(1.0, 0.0, 0.0);
				glVertex3f(vert[vert_pos*6+3]+norm[vert_pos*6+3]*.5f, vert[vert_pos*6+4]+norm[vert_pos*6+4]*.5f, vert[vert_pos*6+5]+norm[vert_pos*6+5]*.5f);
				glVertex3f(vert[vert_pos*6+3]+norm[vert_pos*6+3], vert[vert_pos*6+4]+norm[vert_pos*6+4], vert[vert_pos*6+5]+norm[vert_pos*6+5]);

				// tangent
				glColor3f(0.0, 0.5, 0.0);
				glVertex3f(vert[vert_pos*6], vert[vert_pos*6+1], vert[vert_pos*6+2]);
				glVertex3f(vert[vert_pos*6]+tangent[vert_pos*8]*.5f*Ts, vert[vert_pos*6+1]+tangent[vert_pos*8+1]*.5f*Ts, vert[vert_pos*6+2]+tangent[vert_pos*8+2]*.5f*Ts);

				glColor3f(0.0, 1.0, 0.0);
				glVertex3f(vert[vert_pos*6+3]+tangent[vert_pos*8+4]*.5f*Ts, vert[vert_pos*6+4]+tangent[vert_pos*8+5]*.5f*Ts, vert[vert_pos*6+5]+tangent[vert_pos*8+6]*.5f*Ts);
				glVertex3f(vert[vert_pos*6+3]+tangent[vert_pos*8+4]*Ts, vert[vert_pos*6+4]+tangent[vert_pos*8+5]*Ts, vert[vert_pos*6+5]+tangent[vert_pos*8+6]*Ts);

				// binormal
				glColor3f(0.0, 0.0, 0.5);
				glVertex3f(vert[vert_pos*6], vert[vert_pos*6+1], vert[vert_pos*6+2]);
				glVertex3f(vert[vert_pos*6]+binorm[vert_pos*8]*.5f*Bs, vert[vert_pos*6+1]+binorm[vert_pos*8+1]*.5f*Bs, vert[vert_pos*6+2]+binorm[vert_pos*8+2]*.5f*Bs);

				glColor3f(0.0, 0.0, 1.0);
				glVertex3f(vert[vert_pos*6+3]+binorm[vert_pos*8+4]*.5f*Bs, vert[vert_pos*6+4]+binorm[vert_pos*8+5]*.5f*Bs, vert[vert_pos*6+5]+binorm[vert_pos*8+6]*.5f*Bs);
				glVertex3f(vert[vert_pos*6+3]+binorm[vert_pos*8+4]*Bs, vert[vert_pos*6+4]+binorm[vert_pos*8+5]*Bs, vert[vert_pos*6+5]+binorm[vert_pos*8+6]*Bs);

				vert_pos ++;
			}
			glEnd();


		}
		
	}
}

P.S. it needs these:

void Normalize(float *ptr)
{
	float length = 0;

	length = (float)sqrt((double)*ptr * *ptr + *(ptr+1) * *(ptr+1) + *(ptr+2) * *(ptr+2) );
	*(ptr) /= length;
	*(ptr+1) /= length;
	*(ptr+2) /= length;


}

void Cross(float *destination, float *ptr1, float *ptr2)
{
	*(destination) = *(ptr1+1) * *(ptr2+2) - *(ptr1+2) * *(ptr2+1);
	*(destination+1) = *(ptr1+2) * *ptr2 - *ptr1 * *(ptr2+2);
	*(destination+2) = *ptr1 * *(ptr2+1) - *(ptr1+1) * *ptr2;
}

float Dot(float *ptr1, float *ptr2)
{

	return ( *ptr1 * *ptr2 + *(ptr1+1) * *(ptr2+1) + *(ptr1+2) * *(ptr2+2) );

}

Hi Dorbie,

Thanks so much for your sharing. I will be trying today. Thanks again.

Tony