Skip to content

Instantly share code, notes, and snippets.

@fomkin
Created June 24, 2013 07:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fomkin/5848329 to your computer and use it in GitHub Desktop.
Save fomkin/5848329 to your computer and use it in GitHub Desktop.
package com.tenderowls.geom;
import com.tenderowls.errors.RangeError;
class BezierCurve {
var points:Array<Point<Float>>;
var step:Float;
var __p:Point<Float>;
var t:Float;
/**
* @param points control points
* @param step step 0 ... 1
*/
public function new(points:Array<Point<Float>>, step:Float) {
this.points = points;
this.step = step;
this.t = points.length > 2 ? 0 : 1;
this.__p = new Point<Float>(0, 0);
}
public function next():Point<Float> {
if (!hasNext())
throw new RangeError("Last element reached");
__p.setTo(0, 0);
var n = points.length - 1;
for (i in 0 ... points.length) {
var b = basis(i, n, t);
var p = points[i];
__p.x += p.x * b;
__p.y += p.y * b;
}
t += step;
return __p;
}
public inline function hasNext():Bool {
return t < 1;
}
public function iterator():Iterator<Point<Float>> {
return this;
}
public function setTo(points:Array<Point<Float>>, step:Float) {
this.points = points;
this.step = step;
this.t = 0;
this.__p.setTo(0, 0);
}
private inline static function basis(i:Int, n:Int, t:Float) {
var a = Math2.binomialCoefficient(n, i);
var b = Math.pow(t, i) * Math.pow(1 - t, n - i);
return a * b;
}
}
import haxe.Int64;
using haxe.Int64;
class Math2 {
public inline static function binomialCoefficient(n:Int, k:Int):Float {
var c = 0.0;
if (k >= 0 && k <= n) {
//take advantage of symmetry
if (k > n - k)
k = n - k;
c = 1.0;
for (i in 1 ... k + 1) {
c = c * (n - (k - i));
c = c / i;
}
}
return c;
}
public inline static function factorial64(n:Int):Int64 {
var result:Int64 = Int64.ofInt(1);
var i64 = new MutableInt64();
for (i in 1 ... n + 1) {
i64.setTo(0, i);
result = result.mul(i64);
}
trace(result);
return result;
}
}
@:generic class Point<T> implements PointReadonly<T> {
public var x:T;
public var y:T;
public var z:T;
public function new(x:T, y:T, z:T) {
this.x = x;
this.y = y;
this.z = z;
}
inline public function setTo(x:T, y:T, z:T) {
this.x = x;
this.y = y;
this.z = z;
}
inline public function clone():Point<T> {
return new Point<T>(x, y, z);
}
public function toString():String {
return "(" + x + ", " + y + ", " + z + ")";
}
}
@:generic interface PointReadonly<T> {
var x(default, null):T;
var y(default, null):T;
var z(default, null):T;
function clone():Point<T>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment