How do I generate a random point on a circles circumference in 3D space? [migrated] - math

This question was migrated from Stack Overflow because it can be answered on Mathematics Stack Exchange.
Migrated 24 days ago.
I have a position vector and a normal vector that describes a plane. The plane is always orthogonal to the position vector. On this plane is a circle with its center at the position vector. How do I generate a random point on that circle with a given radius r? I know that in 2d space, I can do
x = cos(2 * PI * random) * radius
y = sin(2 * PI * random) * radius
but... I don't know how to translate that to a circle on a plane.
I tried to find a way to use the position vector and normal vector to generate points, but I just can't think of a correct way to do so. I might not be familiar enough with planes.

At first we need two base vectors in the circle plane.
The first one is arbitrary vector orthogonal to normal n:
Choose component of normal with the largest magnitude, then component with the second magnitude.
Exchange their values, negate the largest, and make the third component zero (note that dot product of result with normal is zero, so they are othogonal)
For example, if n.y is the largest and n.z is the second, make
v = (0, n.z, -n.y)
Then calculate the second base vector using vector product
u = n x v
Normalize vectors v and u (make unit magnitude).
Now we can generate a random point on circumference using center point c (your position, I think):
rho = 2 * PI * random
f.x = c.x + radius * v.x * cos(rho) + radius * u.x * sin(rho)
f.y = c.y + radius * v.y * cos(rho) + radius * u.y * sin(rho)
f.z = c.z + radius * v.z * cos(rho) + radius * u.z * sin(rho)

Related

Upwards tangent vector of triangle in 3D space

I have a triangle in 3D cartesian space, it forms a surface. I have a normal vector of that surface. What I want to find out, is a vector tangent to that surface, which points the most "upwards". (The orange one on image, forgive my paint skills)
Let one triangle edge vector is A. Get perpendicular vector in the plane
P = N x A
and normalize P and A
p = P / len(P)
a = A / len(A)
Any unit vector in the plane is combination of these base vectors
v = p * cos(t) + a * sin(t) (1)
We want that Z-component of v to be maximal (as far as I understand most "upwards")
vz = pz * cos(t) + az * sin(t) (2)
has extremum when it's derivative by t is zero
0 = (pz * cos(t) + az * sin(t))' = -pz * sin(t) + az * cos(t)
tan(t) = az / pz
t = atan2(az , pz)
put t values into (1) and get needed vector v

Cone from direction vector

I have a normalized direction vector (from a 3d position to a light position) and I would like this vector to be rotated by some angle so I can create a "cone".
Id like to simulate cone tracing by using the direction vector as the center of the cone and create an X number of samples to create more rays to sample from.
What I would like to know is basically the math behind:
https://docs.unrealengine.com/latest/INT/BlueprintAPI/Math/Random/RandomUnitVectorinCone/index.html
Which seems to do exactly what Im looking for.
1) Make arbitrary vector P, perpendicular to your direction vector D.
You can choose component with max magnitude, exchange it with middle-magnitude component, negate it, and make min magnitude component zero.
For example, if z- component is maximal and y-component is minimal, you may make such P:
D = (dx, dy, dz)
p = (-dz, 0, dx)
P = Normalize(p) //unit vector
2) Make vector Q perpendicular both D and P through vector product:
Q = D x P //unit vector
3) Generate random point in the PQ plane disk
RMax = Tan(Phi) //where Phi is cone angle
Theta = Random(0..2*Pi)
r = RMax * Sqrt(Random(0..1))
V = r * (P * Cos(Theta) + Q * Sin(Theta))
4) Normalize vector V
Note that distribution of vectors is slightly non-uniform on the sphere segment.(it is uniform on the plane disk). There are methods to generate uniform distribution on the sphere but some work needed to apply them to segment (my first attempt before edit was wrong).
Edit: Modification to make sphere-uniform distribution (not checked thoroughly)
RMax = Tan(Phi) //where Phi is cone angle
Theta = Random(0..2*Pi)
u = Random(Cos(Phi)..1)
r = RMax * Sqrt(1 - u^2)
V = r * (P * Cos(Theta) + Q * Sin(Theta))

Calculating the Coordinates of a Regular Polygon Given Its Center and its side length

I was wondering how to calculate the coordinates of a regular polygon given its center and its side length. I came up with a method for the square already, but I am looking for something that could be applicable to other regular polygons.
Question is poor formulated. But let's assume that the most right edge of regular polygon is vertical. N is number of edges, L is side length. All vertices lie at circle with center given (CX, CY). Radius of this circle:
R = L / (2 * Sin(Pi / N))
I'th vertice of regular N-gon has coordinates:
i = 0..N-1
X[i] = CX + R * Cos(Pi/N * (1 + 2 * i))
Y[i] = CY + R * Sin(Pi/N * (1 + 2 * i))

Height of convex, non-rectangular quad at position x,y?

If I have a convex, non-rectangular quad which is facing "up" (the normal has a positive Z value) how can I find the z coordinate at a given x,y location?
I've already determined that the x,y coordinate is within the quad.
We can assume the quad points are all co-planar if that makes things easier.
The more code-like an answer the more helpful it will be, as mathematical symbols don't really work in code.
The plane passing through a point p=(px,py,pz) which has normal vector n=(nx,ny,nz) is composed by points (x,y,z) which satisfy the equation:
nx * (px-x) + ny * (py-y) + nz * (pz-z) = 0.
If you know that nz != 0 you can compute z:
z = pz + (nx * (px - x) + ny * (py -y))/nz

Plotting a point on the edge of a sphere

So coming from a flash background I have an OK understanding of some simple 2D trig. In 2d with I circle, I know the math to place an item on the edge given an angle and a radius using.
x = cos(a) * r;
y = sin(a) * r;
Now if i have a point in 3d space, i know the radius of my sphere, i know the angle i want to position it around the z axis and the angle i want to position it around, say, the y axis. What is the math to find the x, y and z coordinates in my 3d space (assume that my origin is 0,0,0)? I would think i could borrow the Math from the circle trig but i can't seem to find a solution.
Your position in 3d is given by two angles (+ radius, which in your case is constant)
x = r * cos(s) * sin(t)
y = r * sin(s) * sin(t)
z = r * cos(t)
here, s is the angle around the z-axis, and t is the height angle, measured 'down' from the z-axis.
The picture below shows what the angles represent, s=theta in the range 0 to 2*PI in the xy-plane, and t=phi in the range 0 to PI.
The accepted answer did not seem to support negative x values (possibly I did something wrong), but just in case, using notation from ISO convention on coordinate systems defined in this Wikipedia entry, this system of equations should work:
import math
x = radius * sin(theta) * cos(phi)
y = radius * sin(theta) * sin(phi)
z = radius * cos(theta)
radius = math.sqrt(math.pow(x, 2) + math.pow(y, 2) + math.pow(z, 2))
phi = math.atan2(y, x)
theta = math.acos((z / radius))

Resources