Add security, optimize factorial and clean code

This commit is contained in:
Adrien Ufferte
2025-12-09 11:41:39 +01:00
parent d4fb4cf767
commit 3787d0101a
+23 -24
View File
@@ -1,66 +1,65 @@
class_name Bezier
extends Node
static var factorial_cache: Dictionary = {}
static func bezier_square_error(current_points: Array, ref_points: Array) -> float:
var samples: Array[Vector2] = bezier_sampling(current_points, 25)
var curve: Curve2D = Curve2D.new()
for point: Vector2 in samples:
curve.add_point(point)
var error: float = 0.0
for point: Vector2 in ref_points:
var curve_point: Vector2 = curve.get_closest_point(point)
error += pow(curve_point.distance_to(point), 2.0)
return error
static func bezier_sampling(points: Array, number_of_samples: int) -> Array[Vector2]:
var sample_points: Array[Vector2] = []
if number_of_samples <= 0:
return sample_points
for index: int in range(number_of_samples + 1):
var sample: Vector2 = bezier(float(index) / float(number_of_samples), points)
sample_points.append(sample)
return sample_points
static func bezier(t: float, control_points: Array) -> Vector2:
var degree: int = control_points.size() - 1
var result: Vector2 = Vector2.ZERO
# Compute the weighted sum of the control points using Bernstein polynomials
for point_index: int in range(degree + 1):
var bernstein_weight: float = bernstein(t, degree, point_index)
var weighted_point: Vector2 = bernstein_weight * control_points[point_index]
result += weighted_point
return result
static func bernstein(t: float, m: int, i: int) -> float:
var b_i_m: float = float(binomial(i, m))
var t_i: float = pow(t, i)
var t_m_i: float = pow(1.0 - t, m - i)
var result: float = b_i_m * t_i * t_m_i
static func bernstein(time_ratio: float, degree: int, index: int) -> float:
var binomial_coefficient: float = float(binomial(index, degree))
var time_power_index: float = pow(time_ratio, index)
var inverse_time_power: float = pow(1.0 - time_ratio, degree - index)
var result: float = binomial_coefficient * time_power_index * inverse_time_power
return result
static func binomial(k: int, n: int) -> int:
var n_f: int = factorial(n)
var k_f: int = factorial(k)
var n_k_f: int = factorial(n - k)
return int(float(n_f) / (float(k_f) * float(n_k_f)))
static func binomial(index: int, degree: int) -> int:
if index < 0 or degree < 0 or index > degree:
return 0
var degree_factorial: int = factorial(degree)
var index_factorial: int = factorial(index)
var degree_minus_index_factorial: int = factorial(degree - index)
return int(float(degree_factorial) / (float(index_factorial) * float(degree_minus_index_factorial)))
static func factorial(k: int) -> int:
if k == 0:
return 1
static func factorial(number: int) -> int:
assert(number >= 0, "Factorial is undefined for negative numbers")
if number in factorial_cache:
return factorial_cache[number]
var result: int = 1
for index: int in range(1, k + 1):
result *= index
for value: int in range(1, number + 1):
result *= value
factorial_cache[number] = result
return result