I am trying to finding a random position in torus.
Actually I found a method that finding torus iteratively. But it includes while loop and I don’t want to use while loop in a method while it slows down update duration.
Are there any algorithm for my purpose.
Here is the code that I wrote
Vector3 GetARandomPositionInTorus(Vector3 center)
{
Vector3 dest = transform.position;
while (Vector3.Distance(dest, transform.position) < newCirclePositionMinDistance)
{
Vector3 randomPosition = Random.insideUnitSphere * newCirclePositionMaxDistance;
randomPosition = new Vector3(randomPosition.x, transform.position.y, randomPosition.z);
dest = randomPosition + center;
}
return dest;
Now you have a point that lies within the torus \o/
Here’s some code to demonstrate. I have not factored in the position and orientation of the torus, this is just to show the above steps in practice. Attach to an empty gameObject in a new scene. Hit Play. Left-click in the scene view and change the inspector values while playing.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class RandomPosInTorus : MonoBehaviour
{
public float innerRadius = 2f;
public float outerRadius = 5f;
[Space(20)]
public int iterations = 1000;
public GameObject markerObject;
private List< GameObject > markerList; // object pool. for testing purposes
void Start()
{
markerList = new List< GameObject >();
Generate();
}
void Update()
{
if ( Input.GetKeyDown( KeyCode.Mouse0 ) )
Generate();
}
void Generate()
{
// object pool. for testing purposes. remove old markers each time Generate is called
if ( markerList.Count > 0 )
foreach ( GameObject marker in markerList )
Destroy( marker );
markerList = new List< GameObject >();
float wallRadius = ( outerRadius - innerRadius ) * 0.5f;
float ringRadius = wallRadius + innerRadius; // ( ( max - min ) / 2 ) + min
for ( int i = 0; i < iterations; i ++ )
{
// create marker object
GameObject go;
if ( !markerObject )
{
go = GameObject.CreatePrimitive( PrimitiveType.Sphere );
go.transform.localScale = Vector3.one * 0.05f;
}
else
go = (GameObject)Instantiate( markerObject );
go.name = "Sphere_" + i.ToString();
markerList.Add( go );
// position marker object
Transform tx = go.transform;
tx.position = GetRandomPositionInTorus( ringRadius, wallRadius );
tx.parent = transform;
}
}
Vector3 GetRandomPositionInTorus( float ringRadius, float wallRadius )
{
// get a random angle around the ring
float rndAngle = Random.value * 6.28f; // use radians, saves converting degrees to radians
// determine position
float cX = Mathf.Sin( rndAngle );
float cZ = Mathf.Cos( rndAngle );
Vector3 ringPos = new Vector3( cX, 0, cZ );
ringPos *= ringRadius;
// At any point around the center of the ring
// a sphere of radius the same as the wallRadius will fit exactly into the torus.
// Simply get a random point in a sphere of radius wallRadius,
// then add that to the random center point
Vector3 sPos = Random.insideUnitSphere * wallRadius;
return ( ringPos + sPos );
}
}