|
|
4ef489 |
using System;
|
|
|
4ef489 |
using System.Collections.Generic;
|
|
|
4ef489 |
using System.Linq.Expressions;
|
|
|
4ef489 |
|
|
|
4ef489 |
namespace EllipseTruncate {
|
|
|
4ef489 |
public static class Geometry {
|
|
|
4ef489 |
public static readonly double precision = 1e-8;
|
|
|
4ef489 |
public static readonly double subPrecision = precision*0.1;
|
|
|
4ef489 |
public static readonly double precisionSqr = precision*precision;
|
|
|
4ef489 |
public static readonly double sqrt2Pi = Math.Sqrt(2.0*Math.PI);
|
|
|
4ef489 |
|
|
|
4ef489 |
public static bool isEqual(double a, double b)
|
|
|
4ef489 |
{ return Math.Abs(b - a) <= precision; }
|
|
|
4ef489 |
public static bool isLess(double a, double b)
|
|
|
4ef489 |
{ return a - precision < b; }
|
|
|
4ef489 |
public static bool isGreater(double a, double b)
|
|
|
4ef489 |
{ return b - precision < a; }
|
|
|
4ef489 |
public static bool isLessOrEqual(double a, double b)
|
|
|
4ef489 |
{ return a + precision <= b; }
|
|
|
4ef489 |
public static bool isGreaterOrEqual(double a, double b)
|
|
|
4ef489 |
{ return b + precision <= a; }
|
|
|
4ef489 |
|
|
|
4ef489 |
public static double logNormalDistribuitionUnscaled(double x, double x0, double w) {
|
|
|
4ef489 |
return Math.Exp(-0.5*Math.Pow(Math.Log(x/x0)/w, 2.0))/x;
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static double logNormalDistribuition(double x, double x0, double w) {
|
|
|
4ef489 |
return logNormalDistribuition(x, x0, w)/(w*sqrt2Pi);
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static void truncateInfiniteLine(Rectangle bounds, ref Point p0, ref Point p1) {
|
|
|
4ef489 |
if (p0.isEqual(p1)) return;
|
|
|
4ef489 |
Point d = p0 - p1;
|
|
|
4ef489 |
if (Math.Abs(d.x)*bounds.height > bounds.width*Math.Abs(d.y)) {
|
|
|
4ef489 |
// horizontal
|
|
|
4ef489 |
double k = d.y/d.x;
|
|
|
4ef489 |
p1 = new Point(bounds.x1, p0.y + k*(bounds.x1 - p0.x));
|
|
|
4ef489 |
p0 = new Point(bounds.x0, p0.y + k*(bounds.x0 - p0.x));
|
|
|
4ef489 |
} else {
|
|
|
4ef489 |
// vertical
|
|
|
4ef489 |
double k = d.x/d.y;
|
|
|
4ef489 |
p1 = new Point(p0.x + k*(bounds.y1 - p0.y), bounds.y1);
|
|
|
4ef489 |
p0 = new Point(p0.x + k*(bounds.y0 - p0.y), bounds.y0);
|
|
|
4ef489 |
}
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static class Interpolation<t> {</t>
|
|
|
4ef489 |
public delegate T HalfFunc(T a, double b);
|
|
|
4ef489 |
public delegate T FullFunc(T a, T b);
|
|
|
4ef489 |
|
|
|
4ef489 |
public static FullFunc add;
|
|
|
4ef489 |
public static FullFunc sub;
|
|
|
4ef489 |
public static HalfFunc mul;
|
|
|
4ef489 |
public static HalfFunc div;
|
|
|
4ef489 |
|
|
|
4ef489 |
static Interpolation() {
|
|
|
4ef489 |
{ // add
|
|
|
4ef489 |
ParameterExpression a = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
ParameterExpression b = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
add = Expression.Lambda<fullfunc>(Expression.Add(a, b), a, b).Compile();</fullfunc>
|
|
|
4ef489 |
}
|
|
|
4ef489 |
{ // sub
|
|
|
4ef489 |
ParameterExpression a = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
ParameterExpression b = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
sub = Expression.Lambda<fullfunc>(Expression.Subtract(a, b), a, b).Compile();</fullfunc>
|
|
|
4ef489 |
}
|
|
|
4ef489 |
{ // mul
|
|
|
4ef489 |
ParameterExpression a = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
ParameterExpression b = Expression.Parameter(typeof(double));
|
|
|
4ef489 |
mul = Expression.Lambda<halffunc>(Expression.Multiply(a, b), a, b).Compile();</halffunc>
|
|
|
4ef489 |
}
|
|
|
4ef489 |
{ // div
|
|
|
4ef489 |
ParameterExpression a = Expression.Parameter(typeof(T));
|
|
|
4ef489 |
ParameterExpression b = Expression.Parameter(typeof(double));
|
|
|
4ef489 |
div = Expression.Lambda<halffunc>(Expression.Divide(a, b), a, b).Compile();</halffunc>
|
|
|
4ef489 |
}
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static T linear(T p0, T p1, double l)
|
|
|
4ef489 |
{ return add(mul(p0, 1.0-l), mul(p1, l)); }
|
|
|
4ef489 |
|
|
|
4ef489 |
public static T spline(T p0, T p1, T t0, T t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
double lll = ll*l;
|
|
|
4ef489 |
return add( add( mul(p0, ( 2.0*lll - 3.0*ll + 1.0)),
|
|
|
4ef489 |
mul(p1, (-2.0*lll + 3.0*ll )) ),
|
|
|
4ef489 |
add( mul(t0, ( lll - 2.0*ll + l )),
|
|
|
4ef489 |
mul(t1, ( lll - 1.0*ll )) ));
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static T splineTangent(T p0, T p1, T t0, T t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
return add( mul(sub(p0, p1), 6.0*(ll - l)),
|
|
|
4ef489 |
add( mul(t0, ( 3.0*ll - 4.0*l + 1.0)),
|
|
|
4ef489 |
mul(t1, ( 3.0*ll - 2.0*l )) ));
|
|
|
4ef489 |
}
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static double interpolationLinear(double p0, double p1, double l)
|
|
|
4ef489 |
{ return p0*(1.0 - l) + p1*l; }
|
|
|
4ef489 |
|
|
|
4ef489 |
public static double interpolationSpline(double p0, double p1, double t0, double t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
double lll = ll*l;
|
|
|
4ef489 |
return p0*( 2.0*lll - 3.0*ll + 1.0)
|
|
|
4ef489 |
+ p1*(-2.0*lll + 3.0*ll )
|
|
|
4ef489 |
+ t0*( lll - 2.0*ll + l )
|
|
|
4ef489 |
+ t1*( lll - 1.0*ll );
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static double interpolationSplineTangent(double p0, double p1, double t0, double t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
return (p0 - p1)*6.0*(ll - l)
|
|
|
4ef489 |
+ t0*( 3.0*ll - 4.0*l + 1.0)
|
|
|
4ef489 |
+ t1*( 3.0*ll - 2.0*l );
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static Point interpolationLinear(Point p0, Point p1, double l)
|
|
|
4ef489 |
{ return p0*(1.0 - l) + p1*l; }
|
|
|
4ef489 |
|
|
|
4ef489 |
public static Point interpolationSpline(Point p0, Point p1, Point t0, Point t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
double lll = ll*l;
|
|
|
4ef489 |
return p0*( 2.0*lll - 3.0*ll + 1.0)
|
|
|
4ef489 |
+ p1*(-2.0*lll + 3.0*ll )
|
|
|
4ef489 |
+ t0*( lll - 2.0*ll + l )
|
|
|
4ef489 |
+ t1*( lll - 1.0*ll );
|
|
|
4ef489 |
}
|
|
|
4ef489 |
|
|
|
4ef489 |
public static Point interpolationSplineTangent(Point p0, Point p1, Point t0, Point t1, double l) {
|
|
|
4ef489 |
double ll = l*l;
|
|
|
4ef489 |
return (p0 - p1)*6.0*(ll - l)
|
|
|
4ef489 |
+ t0*( 3.0*ll - 4.0*l + 1.0)
|
|
|
4ef489 |
+ t1*( 3.0*ll - 2.0*l );
|
|
|
4ef489 |
}
|
|
|
4ef489 |
}
|
|
|
4ef489 |
}
|