Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

Trouble finding a random point on the top surface of a brick?

So what i'm trying to create is a function that spits out a random point on the top surface of a brick, regardless of the brick's rotation, position, or size, which is why I am using directions perpendicular to the faces (lookVector, rightVector, etc)

However, my problem with it is that when the brick is rotated 90* of -90*, the random point always becomes the center of the face.

I'm probably doing something stupid, but here's my code:

function getRandomPointOnTopSurface(Part)
	
	local Point = nil
	
	if Part.Shape == Enum.PartType.Block then
		local minLook = Part.CFrame - (Part.CFrame.lookVector * Part.Size.Z/2)
		local maxLook = Part.CFrame + (Part.CFrame.lookVector * Part.Size.Z/2)
		local minRight = Part.CFrame - (Part.CFrame.rightVector * Part.Size.X/2)
		local maxRight = Part.CFrame + (Part.CFrame.rightVector * Part.Size.X/2)
		
		if minLook.z > maxLook.z then -- switches values so the min isn't greater than the max in math.random()
			maxLook = (-Part.CFrame.lookVector * Part.Size.Z/2)
			minLook = (Part.CFrame.lookVector * Part.Size.Z/2)
		end
		if minRight.x > maxRight.x then
			maxRight = Part.CFrame + (-Part.CFrame.rightVector * Part.Size.X/2)
			minRight = Part.CFrame + (Part.CFrame.rightVector * Part.Size.X/2)
		end
		

		Point = Vector3.new(math.random(minRight.x, maxRight.x), (Part.CFrame + (Part.CFrame.upVector * Part.Size.Y/2)).y, math.random(minLook.z, maxLook.z))
		print(Point)
	end
	
	return Point
end

getRandomPointOnTopSurface(workspace.Grass)

Please note I'm not asking for anyone to completely redo my code; I just want to know the flaw with the function -- I can fix it from there

1 answer

Nevermind, i found a solution, and apparently its a lot shorter than i imagined! I'll leave the code here --

Edit: It also works with weddges!


function getRandomPoint(Part)
	
	local Point = nil
	
	if Part:IsA("Part") then
		Point = Part.Position - (Part.CFrame.lookVector * Part.Size.Z/2) - (Part.CFrame.rightVector * Part.Size.X/2)
		
		local howfarlook = math.random(0, Part.Size.Z)
		local howfarright = math.random(0, Part.Size.X)
		
		Point = Point + (Part.CFrame.lookVector * howfarlook) + (Part.CFrame.rightVector * howfarright) + (Part.CFrame.upVector * Part.Size.Y/2)

	elseif Part:IsA("WedgePart") then
		Point = Part.Position - (Part.CFrame.lookVector * Part.Size.Z/2) - (Part.CFrame.rightVector * Part.Size.X/2)
		
		local howfarlook = math.random(0, Part.Size.Z)
		local howfarright = math.random(0, Part.Size.X)
		
		local hypot = math.sqrt(Part.Size.Z^2 + Part.Size.Y^2) -- Length of hypotenuse
		
		local newslantlength = hypot / (Part.Size.Z/howfarlook) -- Length of hypotenuse covering same (relative) z-distance as the selected point
		local subtractY = math.sqrt(newslantlength^2 - howfarlook^2) -- Amount needed to subtract from (relative) y-height to put it on the hypotenuse
		
		Point = Point + (Part.CFrame.lookVector * howfarlook) + (Part.CFrame.rightVector * howfarright) + (Part.CFrame.upVector * (Part.Size.Y/2 - subtractY))
			
		print(Point)
	else
		error("Attmpted to generate point on unsupported part: "..Part.Name)
	end
	
	return Point
end

This discussion is preserved as it was. New answers, comments, and votes are closed.