🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

evenly map points around sphere

Started by
1 comment, last by Dirk Gregorius 3 years, 4 months ago

Say I have phi starting at 0 and ending at 180. Theta starts at 0 and ends at 180, each with 5 points. I am trying to 3d plot phi * theta number of points around a sphere.

This is how I plot a single point.

Real radius(90.0);

Radian theta(90.0);

Radian phi(90.0);

Vector3 result;

result.x = radius * Math::Cos(phi) * Math::Sin(theta);

result.z = radius * Math::Sin(phi) * Math::Sin(theta);

result.y = radius * Math::Cos(theta);

Can anyone help w/ how to plot the number of points evenly around a sphere?

Advertisement

I did this just recently:

	static void GenerateOnSphere (float *samples, int stride, int sampleCount, int seed)
	{
		std::mt19937 generator (seed);
		std::uniform_real_distribution<float> rnd(0.f, 1.f);

		int inputSize = sampleCount * 100; // generating much more samples than finally needed
		std::vector< cy::Point3f > inputPoints(inputSize);
		
		for (int i=0; i<inputSize; i++) // distrubuted randomly over the surface of a sphere
		{
			float theta = 2 * 3.14159265359f * rnd(generator);
			float phi = acos(1 - 2 * rnd(generator));
			inputPoints[i].x = sin(phi) * cos(theta);
			inputPoints[i].y = sin(phi) * sin(theta);
			inputPoints[i].z = cos(phi);
			//Vis::RenderPoint((sVec3&)inputPoints[i], 0,0,1); 
		}

		// but random samples are often not good enough, even if there distribution is guaranteed to be random.
		// so i use said library to reduce the large set to nice poisson samples. 

		cy::WeightedSampleElimination< cy::Point3f, float, 3, int > wse;

		int outputSize = sampleCount;
		std::vector< cy::Point3f > outputPoints(outputSize);
		//wse.Eliminate( inputPoints.data(), inputPoints.size(), 
		//			   outputPoints.data(), outputPoints.size(), true );
		float d_max = 2 * wse.GetMaxPoissonDiskRadius( 2, outputPoints.size(), 4*3.14159265359f );
		wse.Eliminate( inputPoints.data(), inputPoints.size(), 
					   outputPoints.data(), outputPoints.size(),
					   true,  d_max, 2 );

		for (int i=0; i<outputSize; i++)
		{
			float *dst = (float*) (((char*)samples) + i*stride);
			dst[0] = outputPoints[i][0];
			dst[1] = outputPoints[i][1];
			dst[2] = outputPoints[i][2];
		}
		/*for (int i=0; i<outputSize; i++)
		{
			float a = 4*3.14159265359f / float(outputSize);		
			float r = sqrt(4*3.14159265359f / (float(outputSize) * 3.14159265359f));

			Vis::RenderPoint((sVec3&)outputPoints[i], float(i)/1000.f, 1-float(i)/1000.f, 0); 
			Vis::RenderCircle(r, (sVec3&)outputPoints[i], (sVec3&)outputPoints[i], float(i)/1000.f, 1-float(i)/1000.f, 0); 
		}*/
	}

Using the library from here: http://www.cemyuksel.com/cyCodeBase/soln/poisson_disk_sampling.html

It's good. Actually i use it to generate 20 samples, and i generate procedural polyhedra (rocks) from that. The cool thing is if i want 5 faces, i take the first 5 samples. If i want 10 i take the first 10. The samples are ordered so adding one more always results in a poisson distribution. Very useful.

But maybe just that trig part of my code is what you want already.

I use the Fibonacci Spiral for these things. Very easy and very good results. Some resources as example:

https://bduvenhage.me/geometry/2019/07/31/generating-equidistant-vectors.html

http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/

This topic is closed to new replies.

Advertisement