Module:Hct/MathUtils

星剑生留言 | 贡献2025年9月12日 (五) 13:45的版本 (导入1个版本:​搬运自萌娘百科,依CC BY-NC-SA 3.0 CN导入)
(差异) ←上一版本 | 最后版本 (差异) | 下一版本→ (差异)

此模块的文档可以在Module:Hct/MathUtils/doc创建

--[[
  Copyright 2021 Google LLC

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
]]

--[[
  This file has been modified. The original version is at
      https://github.com/material-foundation/material-color-utilities
]]

local MathUtils = {}

--[[
  The signum function.

  @return 1 if num > 0, -1 if num < 0, and 0 if num = 0
]]
function MathUtils.signum(num)
	return num < 0 and -1 or (num == 0 and 0 or 1);
end

--[[
  The linear interpolation function.

  @return start if amount = 0 and stop if amount = 1
]]
function MathUtils.lerp(start, stop, amount)
	return (1.0 - amount) * start + amount * stop;
end

--[[
  Clamps an integer between two integers.

  @return input when min <= input <= max, and either min or max otherwise.
]]
function MathUtils.clampInt(min, max, input)
	if input < min then
		return min;
	elseif input > max then
		return max;
	end
	return input;
end

--[[
  Clamps an integer between two floating-point numbers.

  @return input when min <= input <= max, and either min or max otherwise.
]]
MathUtils.clampDouble = MathUtils.clampInt;

--[[
  Sanitizes a degree measure as an integer.

  @return a degree measure between 0 (inclusive) and 360 (exclusive).
]]
function MathUtils.sanitizeDegreesInt(degrees)
	--[[ Lua中degrees % 360不会出现负数……?
	degrees = degrees % 360;
	if degrees < 0 then
		degrees = degrees + 360;
	end
	return degrees;
	]]
	return degrees % 360;
end

--[[
  Sanitizes a degree measure as a floating-point number.

  @return a degree measure between 0.0 (inclusive) and 360.0 (exclusive).
]]
MathUtils.sanitizeDegreesDouble = MathUtils.sanitizeDegreesInt

--[[
  Sign of direction change needed to travel from one angle to another.

  For angles that are 180 degrees apart from each other, both directions have the same travel
  distance, so either direction is shortest. The value 1.0 is returned in this case.

  @param from The angle travel starts from, in degrees.
  @param to The angle travel ends at, in degrees.
  @return -1 if decreasing from leads to the shortest travel distance, 1 if increasing from leads
      to the shortest travel distance.
]]
function MathUtils.rotationDirection(from, to)
	local increasingDifference = MathUtils.sanitizeDegreesDouble(to - from);
	return (increasingDifference <= 180.0) and 1.0 or -1.0;
end

--[[ Distance of two points on a circle, represented using degrees. ]]
function MathUtils.differenceDegrees(a, b)
	return 180.0 - math.abs(math.abs(a - b) - 180.0);
end

--[[ Multiplies a 1x3 row vector with a 3x3 matrix. ]]
function MathUtils.matrixMultiply(row, matrix)
	local a = row[1] * matrix[1][1] + row[2] * matrix[1][2] + row[3] * matrix[1][3];
	local b = row[1] * matrix[2][1] + row[2] * matrix[2][2] + row[3] * matrix[2][3];
	local c = row[1] * matrix[3][1] + row[2] * matrix[3][2] + row[3] * matrix[3][3];
	return {a, b, c};
end

--[[ Cube root of num. ]]
function MathUtils.cbrt(num)
	return MathUtils.signum(num) * math.abs(num) ^ (1 / 3);
end

return MathUtils