Math - How can I make a part smaller the farther it is away from the origin?

This is what I have currently:

What I want:

I know about 10/distance, but I don’t know how to make it noticeably smaller the farther it is.
The most I have is local size = 10/((part1.Position - pos).Magnitude).
(pos being the raycast result pos, part1 is the origin)

1 Like

I cant link to the post but try searching on google as i an on mobile

I tried looking it up but all I found is people saying they can’t make anything smaller or just bugs.

anyone have any ideas other than looking it up

You could use Vector3:Dot like this:

local Size = DefSize * UnitRay:Dot(LookVector)

UnitRay is the position you shot the ray towards except with exactly 1 magnitude (you can use Vector3.Unit to turn any vector into an unit vector) LookVector is the part’s CFrame.LookVector and DefSize is the biggest size possible you want as a Vector3.

You might have to tweak things a bit as this will be a bit too linear and hard to notice but Vector3:Dot returns a number so you should be able to do a lot with it.

for some reason the size.x and y are within 0.8, and the sizes are very close together

This is because the rays arent too far away from eachother, you can try mapping the numbers you get to a more suitable range by multiplying them and subtracting the lowest amount you can get possible

this would make it smaller as you look away from the object, dot products are positive when the two vectors point in the same direction, 0 when one points at a right angle, and negative when the vectors point away from each other. Wolfire explains this by using dot products to calculate line-of-sight.

Your distance calculation is correct, more scaling may be what you need. When using it as a divisor you end up getting smaller and smaller results, the scaling factor will drop off instead of turning negative.

if you want linear scaling (with a minimum) you could use this local scale = math.max(0.1, 10 - magnitude)

Also the example you’ve provided might have some randomness added to it as there are smaller circles closer to middle than some larger ones etc. so after getting scaling properly you could try adding some randomness via math.random().

Well I tried it and it does kinda work, but its either really small or really big(up to 10) so I changed the max to 1 and now its only small. they are all pretty much the same size, the only thing that changes the size is putting the part farther away

Ah I think I misunderstood what you wanted. I think it would help to post the script you are working with. @TheFirepc_TRofical was correct the dot product can get you smaller sizes as the rays hit farther from the center.

This is what I have so far

local part1 = script.Parent

-- axis: center line of cone
-- angle: angle from center to edge of cone
-- returns: a random unit vector inside the cone, evenly distributed along the partial surface of a unit sphere.

for i = 1,100 do
	local function RandomCone(axis: Vector3, angle: number)
	local cosAngle = math.cos(angle)
	local z = 1 - math.random()*(1 - cosAngle)
	local phi = math.random()*math.pi*2
	local r = math.sqrt(1 - z*z)
	local x = r * math.cos(phi)
	local y = r * math.sin(phi)
	local vec =, y, z)
	if axis.Z > 0.9999 then
		return vec
	elseif axis.Z < -0.9999 then
		return -vec
	local orth = Vector3.zAxis:Cross(axis)
	local rot = math.acos(axis:Dot(Vector3.zAxis))
	return CFrame.fromAxisAngle(orth, rot) * vec

local function GetPartsInFrontRay(start)
	local params =
	params.FilterDescendantsInstances = {start}
	params.FilterType = Enum.RaycastFilterType.Blacklist

	local vector = part1.CFrame.LookVector
	--local origin = part1.Position
	---- origin can be your lookvector, it doesn't matter too much, it just needs to be a position
	--local Spread = 5 -- in studs, large amound so you know it more noticable
	----local mouseposition = player:GetMouse.Hit.Position -- get the position of the mouse's position in 3d space
	--local mouseposition = part1.CFrame.LookVector
	--local offset =,Spread),math.random(-Spread,Spread),math.random(-Spread,Spread))
	--mouseposition = mouseposition + offset -- add the offset to the end position ( in this case the mouse position)
	--local Direction = (mouseposition - origin).Unit -- direction 

	--local rayresult = workspace:Raycast(origin,direction*100,raycastparams) -- all together now, cast the ray!

	-- angle of the cone, i.e. the largest angle off the firing axis you could be
	local SPREAD = math.rad(15)

	-- speed of the bullet (can also be random if you want)

	--part1.AssemblyLinearVelocity = RandomCone(part1.CFrame.LookVector, SPREAD)

	local ray = workspace:Raycast(start.Position, RandomCone(part1.CFrame.LookVector, SPREAD) * 150, params)

	if ray and ray.Instance then
		return ray.Instance,ray.Normal,ray.Position

local part,normal,pos = GetPartsInFrontRay(part1)
	if part then
		local water = game.ReplicatedStorage.water:Clone()
		water.Parent = workspace
		water.CFrame =, pos+normal)
		water.WeldConstraint.Part1 = part
		local size = 10/((part1.Position - pos).Magnitude)
		local DefSize = 1
		--local size = DefSize * pos.Unit:Dot(part1.CFrame.LookVector)
		water.Size =,size,0.1)

The part im working on is a bit down, right under if part then

This is the topic!

well it kinda worked, but once again, anothe issue. For me the parts got smaller the close the part got, and not enough scaling.

anyone have anything yet? ive been looking and trying messing with solutions but i havent found anything yet

untested, this may not work at all but if it does work hopefully it will be what you want

you can calculate the max distance as the edge length of your cone with the height being the distance of a raycast going straight through the center of said cone

local D = Distance/MaxDistance
local MinSize = 1
local MaxSize = 5
local Size = -MaxSize * D*(D-2) + MinSize;

well it did work, again. But the parts got smaller the closer the origin got to the wall, and not enough scaling

if you are having issues just swap min and max size to reverse it. And there can be as much scaling as you like? at the edge of your cone, it will be the min size and at the center, it will be the max so just play around with the values

Do you want the size of the parts to scale as they are initially created, based on the angle of their direction vector to the RandomCone’s axis vector?

Or do you want the size of the parts to scale when their raycast hits something, based on the distance between their hit Position and the hit Position of a raycast cast along the cone’s central axis?

Or do you want something else?