How to create a 3D wind system revolving around a line

Ok this is kind of hard to explain, but I want to make a wind system that revolves around a line at any distance from that line, like wind travelling in parallel paths around a globe. By this I mean I provide a function a 3D point and it gives me the direction of the wind at that point.

To illustrate this, here is what I mean in circular form.

The wind is revolving clockwise around the origin of the circle, even when you go closer.

In a similar vein, I want to make what is basically an infinite amount of those circles sandwiched together:

Orange is the line that they’re revolving around. Green is the wind direction at that point, which is what I’m trying to get.
Note that the wind paths are all parallel to each other, they dont meet at a specific spot.

I don’t know how to even start this, because I’ve been having trouble with just the 2d version.
Also keep in mind that the sphere is just to show that getting closer to the line doesn’t change the wind path, in reality I guess it’s a cylinder of any size that the wind is revolving around.

I’d also like a way to reverse this wind to go the opposite direction.

These concepts are somewhat foreign to me, and I just want an explanation of how each of these problems could be solved. I am not asking for you to script the system for me.

UPDATE:
I figured it out a while ago but forgot to update this post.
This is a module script I made that does exactly what I wanted

local Wind = {}

local lineOrigin = game.ServerStorage.WindConfigs.WindLineOrigin.Value.Unit
local lineDirection = game.ServerStorage.WindConfigs.WindLineDirection.Value.Unit

function closestPointFromPosition(pos)
	local dir = (pos-lineOrigin)
	local dist = dir.Magnitude
	local ray
	if dir.Unit:Dot(lineDirection) >= 0 then
		ray = Ray.new(lineOrigin,lineDirection)
	else
		ray = Ray.new(lineOrigin,-lineDirection)
	end
	return ray:ClosestPoint(pos)
end

function windDirectionFromPoints(point1, linePos, clockwise)

	local directionToCircle = (point1 - linePos).Unit
	local tangentDirection = directionToCircle:Cross(lineDirection)

	if not clockwise then
		tangentDirection = -tangentDirection
	end

	return tangentDirection
end

local clockwise = true

function Wind.getWindAtPos(pos)
	lineOrigin = game.ServerStorage.WindConfigs.WindLineOrigin.Value.Unit
	lineDirection = game.ServerStorage.WindConfigs.WindLineDirection.Value.Unit

	local linePos = closestPointFromPosition(pos)
	local tangentVector = windDirectionFromPoints(pos, linePos, clockwise)
	
	return tangentVector
end

return Wind

Anyone is free to use it if they want!

Here’s it in action with my wind particles swirling in a circle around an “island”

9 Likes

What is the wind? A particle system?

7 Likes

Oh, by wind I just mean a direction that is tangent to the circular path.
I’ll clarify in the original post.

I probably explained that bad, basically I am trying to find the green arrow given any point in 3D space relative to that line:

3 Likes

I think I am very under-qualified to help, but I would go about it by creating multiple alternating circles on the edges of the sphere. It sounds really cool though!

4 Likes

I have considered this but I know there’s a math based way to do it, I just can’t seem to figure that out.
I think finding the closest point on the line to the point in 3D space you provide would be the first step, then doing some trigonometry, but I can’t wrap my head around it.

4 Likes

What’s your use case for this by chance? Why does it HAVE to revolve around a circle? If you’re trying to make a foliage sway effect you could utilize Perlin Noise with a sin wave function, or both sin and cos, to get a movement effect…

3 Likes

This sounds awful lot like a vector field. You can definitely do it in Roblox, but your brain will probably explode.
image

You know how Roblox terrain is stored? When you access the terrain through a script, it’s represented as voxels in a 3-dimensional table. Each voxel is 4 studs wide. You can do something similar but instead of storing terrain you just store Vector3s. For your particular use case, you want to create a vortex inside the vector field.

As your object exist in the world, you look in the table for the closest “wind voxels”, get the average Vector3 at that location, and use it to push the object. You do this every frame and it will be a pretty close simulation of wind. You just made fluid dynamics in Roblox lol

3 Likes

I’m using it to make an airship game where you want to be travelling downwind to go as fast as possible, and I don’t want to overcomplicate the wind system, which is why I just want parallel wind direction in 3D space.

3 Likes

I’ll have to look into it, I think I’ll try some more with the getting the tangent of a circle that the 3D point you have lies on, but if I can’t get that to work I’ll research this.

3 Likes

Found a reddit post that might work for you: Reddit - Dive into anything

4 Likes