Improvements to a functioning Buoyancy Calculator?

Hello there. Just something small I need help on. I made two different float functions which calculate the force needed to push a boat upwards. I am not happy about what it looks like.
for example I am currently using this (VerticalSpeed / abs(VerticalSpeed)) to get a unit direction of the vertical speed. I feel this is not good enough. Is there a better way?

The code works fine. This is the outcome. https://gyazo.com/df943a85b01ab375816faea0081d9dc0 Does anyone have any ideas to improve this?


function SeaPhysics:GetDifferenceForce(CurrentPosition,VerticalSpeed,PartMass)
	-- Looks messy. I might have to refactor this later
	EastWestHeight = sin(rad((CurrentPosition.X*self.WaveSize + self.Time)))
	NorthSouthHeight = sin(rad((CurrentPosition.Z*self.WaveSize + self.Time))) 
	ElevationTarget = (EastWestHeight+NorthSouthHeight)*self.WaveHeight
	DragForce = (VerticalSpeed == 0 and 0) or (VerticalSpeed) * abs(VerticalSpeed) * (VerticalSpeed / abs(VerticalSpeed)) * -DRAG_FORCE_COEFFICIENT -- Strange
	
	ElevationDifference = ElevationTarget - CurrentPosition.Y
	ResultingForce = (ElevationDifference * self.P) + DragForce -- Better way to get this?

	return ResultingForce
end

function SeaPhysics:CalculateBuoyancyForce(CurrentPosition,VerticalSpeed,UnitDisplacement)
	-- Looks messy. I might have to refactor this later
	EastWestHeight = sin(rad((CurrentPosition.X*self.WaveSize + self.Time)))
	NorthSouthHeight = sin(rad((CurrentPosition.Z*self.WaveSize + self.Time))) 
	ElevationTarget = (EastWestHeight+NorthSouthHeight)*self.WaveHeight
	ElevationDifference = ElevationTarget - CurrentPosition.Y
	
	DragForce = (VerticalSpeed == 0 and 0) or abs(VerticalSpeed) * abs(VerticalSpeed) * (VerticalSpeed / abs(VerticalSpeed))-- * -self.D 	-- EEEWWW
	DisplacedVolume = ElevationDifference > 0 and ElevationDifference * UnitDisplacement or 0		-- OH DEAR
	ResultingForce = (DisplacedVolume * GRAVITY * WATER_DENSITY) + DragForce		-- I AM HAVING A BRAIN SEIZURE too much maths
	
	return ResultingForce
end

4 Likes

If you mean getting the direction of your speed (ie, -1 or +1) then you can just use math.sign(VerticalSpeed)

See here: New Lua functions, math.sign and math.clamp

2 Likes

Don’t declare functions inside a table via : if you aren’t going to be using self (and assuming it references to an object created from a constructor function which inherits methods or properties from a class). They aren’t methods, so just declare them as ..

There’s no point in having references to functions. However, for readability, sure, but for performance, no - there is literally a stupidly negligible difference. Don’t micro optimize for god’s sake.

am currently using this (VerticalSpeed / abs(VerticalSpeed)) to get a unit direction of the vertical speed

If VerticalSpeed is a Vector, index it with the Unit property which would calculate the unit as VerticalSpeed/ VerticalSpeed.Magnitude and caches it so it doesn’t calculate it unnecessarily every time you index it again.

If you’re a part of the beta program, you can also turn on the new native “fast” vector. I my self have seen noticeable differences.

There’s no need of (), and has a higher precedence than or, so should be fine. Again, it’s mostly if you’re going for readability, if so, then leave it as it is.

 DragForce = (VerticalSpeed == 0 and 0) or (VerticalSpeed) * abs(VerticalSpeed) * (VerticalSpeed / abs(VerticalSpeed)) * -DRAG_FORCE_COEFFICIENT -- Strange

Lastly, I also like the fact that your code is clean and making use of constants (not really constants).

3 Likes

Thanks for all your help. I will look into this and see what I can do to make it better.

1 Like