i am looking for an algorithm ( in pseudo code) that generates the 3d coordinates of a sphere mesh like this:
the number of horizontal and lateral slices should be configurable
i am looking for an algorithm ( in pseudo code) that generates the 3d coordinates of a sphere mesh like this:
the number of horizontal and lateral slices should be configurable
If there are M lines of latitude (horizontal) and N lines of longitude (vertical), then put dots at
(x, y, z) = (sin(Pi * m/M) cos(2Pi * n/N), sin(Pi * m/M) sin(2Pi * n/N), cos(Pi * m/M))
for each m in { 0, ..., M } and n in { 0, ..., N-1 } and draw the line segments between the dots, accordingly.
edit: maybe adjust M by 1 or 2 as required, because you should decide whether or not to count "latitude lines" at the poles
FWIW, you can use meshzoo (a project of mine) to generate meshes on spheres very easily.
You can optionally use optimesh (another one out of my stash) to optimize even further.
import meshzoo
import optimesh
points, cells = meshzoo.icosa_sphere(10)
class Sphere:
def f(self, x):
return (x[0] ** 2 + x[1] ** 2 + x[2] ** 2) - 1.0
def grad(self, x):
return 2 * x
points, cells = optimesh.cvt.quasi_newton_uniform_full(
points, cells, 1.0e-2, 100, verbose=False,
implicit_surface=Sphere(),
# step_filename_format="out{:03d}.vtk"
)
This is just off the top of my head without testing. It could be a good starting point.
This will give you the most accurate and customizable results with the most degree of precision if you use double.
public void generateSphere(3DPoint center, 3DPoint northPoint
, int longNum, int latNum){
// Find radius using simple length equation
(distance between center and northPoint)
// Find southPoint using radius.
// Cut the line segment from northPoint to southPoint
into the latitudinal number
// These will be the number of horizontal slices (ie. equator)
// Then divide 360 degrees by the longitudinal number
to find the number of vertical slices.
// Use trigonometry to determine the angle and then the
circumference point for each circle starting from the top.
// Stores these points in however format you want
and return the data structure.
}
This is a working C# code for the above answer:
using UnityEngine;
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class ProcSphere : MonoBehaviour
{
private Mesh mesh;
private Vector3[] vertices;
public int horizontalLines, verticalLines;
public int radius;
private void Awake()
{
GetComponent<MeshFilter>().mesh = mesh = new Mesh();
mesh.name = "sphere";
vertices = new Vector3[horizontalLines * verticalLines];
int index = 0;
for (int m = 0; m < horizontalLines; m++)
{
for (int n = 0; n < verticalLines - 1; n++)
{
float x = Mathf.Sin(Mathf.PI * m/horizontalLines) * Mathf.Cos(2 * Mathf.PI * n/verticalLines);
float y = Mathf.Sin(Mathf.PI * m/horizontalLines) * Mathf.Sin(2 * Mathf.PI * n/verticalLines);
float z = Mathf.Cos(Mathf.PI * m / horizontalLines);
vertices[index++] = new Vector3(x, y, z) * radius;
}
}
mesh.vertices = vertices;
}
private void OnDrawGizmos()
{
if (vertices == null) {
return;
}
for (int i = 0; i < vertices.Length; i++) {
Gizmos.color = Color.black;
Gizmos.DrawSphere(transform.TransformPoint(vertices[i]), 0.1f);
}
}
}
just a guess, you could probably use the formula for a sphere centered at (0,0,0)
x²+y²+z²=1
solve this for x, then loop throuh a set of values for y and z and plot them with your calculated x.
sqrt()
, which I believe is expensive. –
Jallier © 2022 - 2024 — McMap. All rights reserved.