- Home /
Find Evenly Spaced Samples Over An Aribtrary Arc
I would like to create a fan located at a specific vector and point at another vector. Then a number of samples should scatter evenly spaced and evenly distributed over that arc. How do I find these samples? I know all paramters (length of the cone, angle, source vector and target, and number of samples).
Any help/hint would be greatly appreciated.
Answer by robertbu · Apr 14, 2013 at 06:01 PM
Create two vectors going from the point of the fan to each end of the fan.
Use Vector2.Angle() to figure out the angle between the two vectors.
Calculate the angle of rotation to place each item. If you have n items to place, your delta angle will be total angle divided by n-1.
Figure out the axis of rotation. If the two vectors are arbitrary, you can use Vector3.Cross() to calculate the axis.
Create a rotation representing the delta_angle rotation around using Quaternon.AngleAxis() using the axis from step 4.
To actually place the items, start with the first vector from step 1 and in a loop:
pos = fan_point + qRot * v3Start;
...where 'fan_point' is the point of the fan, qRot is the rotation calculated in step 5, and v3Start the first vector from step 1,
Accoring to this I will do the following: Find the angle of the fan: For that I use a given vector3. Then I calculate the angle of a 2d vector using the x and z coordinates of that given vector via $$anonymous$$athf.Atan2(vectorDirection.z, vectorDirection.x).
Then I create two new vectors with polar offset using the lenth of the cone (or distance between origin and new point), a highest angle to the left and to the right and fill the remaining samples inbetween according to each individual angle between the two edges.
After that I calculate the axis via cross product, using the two edges translated to 3d via Vector3.Set(vecLeftEdge.x, dunno, vecLeftEdge.z) and Vector3.Set(vecRightEdge.x, dunno, vecRightEdge.z) and then proceed with calculating the rotation in 3d and following through the loop.
Do I miss something or is this correct?
You asked for an arbitrary arc which to me meant any two vectors in 3D space. ATan2() will only work if your objects are aligned with a plane using two axes. I don't know the form of your inputs, but here is a bit of sample code for the above steps:
using UnityEngine;
using System.Collections;
public class FanPlacement : $$anonymous$$onoBehaviour {
public Vector3 v3Pivot = new Vector3(0.0f, -.5f, 0.0f); // World point of pivot
public Vector3 v3End1 = new Vector3(-2.0f, 2.0f, 0.0f); // World point of left end of fan
public Vector3 v3End2 = new Vector3(2.0f, 2.0f, 0.0f); // World point of right end of fan
public int count = 5; // number of items to place
void Start () {
Vector3 v3A = v3End1 - v3Pivot; // Step 1
Vector3 v3B = v3End2 - v3Pivot;
float total_angle = Vector3.Angle (v3A, v3B); // Step 2
float delta_angle = total_angle / (float)(count - 1); // Step 3
Vector3 axis = Vector3.Cross(v3A, v3B); // Step 4
Quaternion q = Quaternion.AngleAxis (delta_angle, axis); // Step 5
for (int i = 0; i < count; i++) {
GameObject go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
go.transform.position = v3Pivot + v3A; // Step 6
v3A = q * v3A;
}
}
}
Thank you for the sample code. I will use it to solve this issue.