A question about circle (in triangles) and normals

Started by
8 comments, last by mldaalder 19 years, 2 months ago
Hello, I have 2 questions related to math.
  • How can I draw a circle with equally sized (area wise) triangles? Preferably compatible with Triangle Strips and glDrawArrays, it doesn't need to be a perfect circle, I just need a shape resembeling a circle that I can dynamicly calculate (or perferably pre calculate).
  • How can I calculate normals with an arbitrary object with only vertex data designed for triangle strips?
Now, for some background. I'm trying to design a StarGate (with OpenGL as rendering API), it goes reasonably well, considering I've never tried this complex and I've only worked for 2 weeks (2 hours a day at most). I first tried to do the Event Horizon, utilizing Yann Lombards Water Solver. But I've desided to make my own (I need to learn anyway:P). I had a couple of reasons for that: 1. It's a square, and I need a circle. 2. I got a strange bug, the wave not appearing where it should appear and it was stretched, but the normals updated correctly. What I already have: I have the main ring, the inner track globally done, the rest of the details will be done through bump mapping and the sorts (could prove another interresting question later on). As you can see it looks very bland for 20k+ polygons (ignore the 30 sections line in the screenshot, there are actually 257 sections, see wireframe image) this comes because it lacks normals to make it lit. And the blue disk are my current attempt to my first question. As you can see in the wireframe screenshot the triangles are small in the center and big in the edges, that is what I want to prevent to some order. It wouldn't look nice when physics are applied to it. As you can see I've used the cos and sin functions (and basic trigonmetry (sp, it's late)) to make it (the same with the main ring and inner track). I hope you can help me! Thank you for your time in advanced, PS If this is in the wrong forum, please move it! [Edited by - mldaalder on January 17, 2005 12:31:02 PM]
Advertisement
if you want to do distortion, yeah, a sphere with an even distribution of points is always handy.

Now, to build such a sphere, you can recursively tessalate a geodesic sphere. Sounds complicated, but it's quite simple.

YOU start off with a nice, well distributed volume. I use a dodecahedron (like a 20 faced dice). Then you find the midpoints of the each edges, and interconnect them. That will split your triangles into 4 smaller triangles with equal surface.

ect... until you reached a satisfying level of detail.

If you want strips, such a surface can be stripified efficiently (look at tools that convert triangles into strips). It will peel like an orange.

For distortion effects, that can get complicated. I've worked a bit on something like that actually. If I can find the code, I'll make it available.

What it was was a shield effect for a game. You get bullets hitting the spherical shield, sending ripples on the shield, like rain drops.

So I guess, In the extreme even of a stargate portal opoening up, that could work (with a bit more noise and careful considerations).



Everything is better with Metal.

Quote:Original post by oliii
YOU start off with a nice, well distributed volume. I use a dodecahedron (like a 20 faced dice). Then you find the midpoints of the each edges, and interconnect them. That will split your triangles into 4 smaller triangles with equal surface.

not equal. the middle one is bigger.

if you want really uniform distributions i think doing some sort of repulsive point simulation is best.
here it is.

I must warn you, the code is very old, and not too good looking. there are very little optimisations. Keys are, w/s/a/d for moving camera, 'h' for switching wireframe on/off (bash it a couple of times), space for creating a distortion (bash it too). Avoid clicking the mouse button, or you'll have to pull back the camera a couple of mneters ('s' key).

now the code is just a tesselated geodesic sphere. The water distortion is some cheap stuff, which is nothing more than the classic 2D raindrop effect based on filters. Still, it looks good. YOu can improve it with some more fancy distortion effects (perlin noise springs to mind).

It's much faster than doind the 'spring' system though.

ditch the texture coordinates calculations. It's rubbish. The tricky part is to actually texture such a sphere. You can't just use a plain 2D texture, but rather, you have to do an 'authalic' texture.

Everything is better with Metal.

Quote:Original post by Eelco
Quote:Original post by oliii
YOU start off with a nice, well distributed volume. I use a dodecahedron (like a 20 faced dice). Then you find the midpoints of the each edges, and interconnect them. That will split your triangles into 4 smaller triangles with equal surface.

not equal. the middle one is bigger.

if you want really uniform distributions i think doing some sort of repulsive point simulation is best.


yeah, OK. If you really want to be anal about it, they aren't *exactly* identical. Plus you'll have some with 5 neighbours, and some with 6 neighbours, but it's being rather picky.

Everything is better with Metal.

Thanks for your (fast) replies!

Well I don't need a *perfect* distribution, just a more even distribution that the current one.

Thanks for the program oliii. I suppose I could spit it through and convert it to a circle (disk not sphere).

And about the Texture Coordinate Calculations
I was refering to the main ring and inner ring (the one where the glyps reside). They are going to have detail textures (so to say) there are patterns on them. But I'm first going to try that myself, I've been working on the equal distribution for a couple of days without real progress...

These are the patterns I'm speaking of (encircled by red):
Hmmm... After some time spending with the program. I can't really figure it out...:(

Thanks anyway.

You don't happen to have any other idea's (feel free to spout out math) on how to draw a disk with only triangles (which are more or less evenly spaced)? The edges need to be fixed anyway.

Would it be an idea to check if points are inside a circle or not?
And as soon as all the points are out of the circle I stop?

Well, let's say I want a grid of 256x256 (accellerated through Vertex Arrays) points which go up and down (or in and out which is the mostlikly sollution I'm going to do).

Would such a thing be a smart thing to do? Or are there far better ways?



And then there is the issue of the Normals. As I said, I don't have face data (not as such atleast). How would I go and generate it?
well, how about this. You just create a huge page of equilateral triangles. Then you find the triangles that fit the disk, and you organise it into a strip. That should give a good approximation of a disk, it doesn't have to be accurate since the rim of the disk will be hidden by the stone ring.

Right now, I just can't think of a procedural (fractal, recursion would be elegant) way of generating a better disk approximation with equilateral triangles.

Everything is better with Metal.

...which is actally what you proposed. I'd try that.

Everything is better with Metal.

Well, I'm still working on the disk, but I've still not gotten my answer to my Normal question.

This is my current code I use to calculate the normals:
void cStarGateRing::CalcNormals(){	delete [] Normals;	Normals = new double[numVertices*3];	for(int i=0;i<numVertices;i++)		Normals=0;	cVector* TempNormals = new cVector[numVertices];	cVector* TempUnNormals=new cVector[numVertices];	struct Polygon	{		int vectors[3];	};	unsigned int PosHelper=0;	Polygon* PolygonData = new Polygon[numVertices-2];	cVector vPoly[3];	cVector vVector1, vVector2, vNormal;	for(int i=0;i<(numVertices-2)/3;i++)	{		PolygonData.vectors[0]=PosHelper+0;		PolygonData.vectors[0]=PosHelper+1;		PolygonData.vectors[0]=PosHelper+2;		vPoly[0].x = Vertices[PosHelper+0];		vPoly[0].y = Vertices[PosHelper+1];		vPoly[0].z = Vertices[PosHelper+2];		PosHelper+=3;		PolygonData.vectors[1]=PosHelper+0;		PolygonData.vectors[1]=PosHelper+1;		PolygonData.vectors[1]=PosHelper+2;		vPoly[1].x = Vertices[PosHelper+0];		vPoly[1].y = Vertices[PosHelper+1];		vPoly[1].z = Vertices[PosHelper+2];		PosHelper+=3;		PolygonData.vectors[2]=PosHelper+0;		PolygonData.vectors[2]=PosHelper+1;		PolygonData.vectors[2]=PosHelper+2;		vPoly[1].x = Vertices[PosHelper+0];		vPoly[1].y = Vertices[PosHelper+1];		vPoly[1].z = Vertices[PosHelper+2];		PosHelper+=3;		vVector1 = vPoly[0] - vPoly[2];		vVector2 = vPoly[2] - vPoly[1];		vNormal  = vVector1.Cross(vVector2);		TempUnNormals = vNormal;		vNormal.Normalize();		TempNormals = vNormal;	}	cVector vSum(0.0, 0.0, 0.0);	cVector vZero = vSum;	int shared=0;	PosHelper = 0;	for(int i=0; i<numVertices; i++)	{		for(int j = 0; j < numVertices-2; j++)		{			if(PolygonData[j].vectors[0] == i || 				PolygonData[j].vectors[1] == i || 				PolygonData[j].vectors[2] == i)			{				vSum += TempUnNormals[j];				shared++;			}		}      		vSum.x /= double(shared);		vSum.y /= double(shared);		vSum.z /= double(shared);		TempUnNormals = vSum;		TempUnNormals.Normalize(); 		Normals[PosHelper+0] = TempNormals.x;		Normals[PosHelper+1] = TempNormals.y;		Normals[PosHelper+2] = TempNormals.z;		PosHelper+=3;		vSum = vZero;		shared = 0;	}	delete [] PolygonData;	delete [] TempUnNormals;	delete [] TempNormals;}


And this is the result:

As you can see it isn't really working...

And before you ask, it is based upon DigiBens 3DS Loader. It was the closest example I could find for my situation. Although with 3DS there is actual face data which I don't have.

The Polygon struct contains indices to the Vertex array (if I didn't make any mistake that is).

Vertices and Normals are double arrays which contain x,y and z values.

I hope anyone can find the problem...

This topic is closed to new replies.

Advertisement