2017-08-10 5 views
0

C#の「ポリ調和スプライン」の実装を検索します。私はこのライブラリを見つけただけですAltaxo。私は、ライブラリがnugetを介して利用可能な場所を検索し、ライセンスはapacheまたはmitです。ポリ調和スプラインの実装c#

私のユースケースは、2次元マップ上の定点の平均温度を見つけることです。 (:0、Y:0温度:10°X)

  • POSITION2(X:0、Y:30温度:100℃)
  • POSITION3(X:40 Y:0温度

    • POSITION1に例えば:50℃)
    • POSITION4(X:30 Y:30温度:20℃)

    赤い点が計算された値です。

    Temperature map

    コード例は

    using Altaxo.Calc.Interpolation; 
    using Altaxo.Calc.LinearAlgebra; 
    using System.Collections.Generic; 
    using System.Linq; 
    
    public class Spline 
    { 
        private PolyharmonicSpline _spline; 
    
        public Spline() 
        { 
         var items = new List<TemperaturePosition>() 
         { 
          new TemperaturePosition(0,0,10), 
          new TemperaturePosition(0,30,100), 
          new TemperaturePosition(40,0,50), 
          new TemperaturePosition(30,30,20), 
         }; 
    
         var xCoordinates = items.Select(o => o.X).ToArray(); 
         var yCoordinates = items.Select(o => o.Y).ToArray(); 
         var values = items.Select(o => o.Temperature).ToArray(); 
    
         this._spline = new PolyharmonicSpline(); 
         this._spline.Construct(new DoubleVector(xCoordinates), new DoubleVector(yCoordinates), new DoubleVector(values)); 
        } 
    
        public double Calculate(double x, double y) 
        { 
         return this._spline.GetInterpolatedValue(x, y); 
        } 
    } 
    
    public class TemperaturePosition 
    { 
        public double X { get; set; } 
        public double Y { get; set; } 
        public double Temperature { get; set; } 
    
        public TemperaturePosition(double x, double y, double temperature) 
        { 
         this.X = x; 
         this.Y = y; 
         this.Temperature = temperature; 
        } 
    } 
    
  • 答えて

    1

    実際にはスプラインの代わりに重心補間を使用して、同様の補間を自分で実装することは困難ではありません。お役に立つかもしれないpractical guide to barycentric interpolationですいくつかのコードの場合

    、このanswer on gamedev.stackexchange.com見てい:

    これを持っ
    // Compute barycentric coordinates (u, v, w) for 
    // point p with respect to triangle (a, b, c) 
    void Barycentric(Point p, Point a, Point b, Point c, float &u, float &v, float &w) 
    { 
        Vector v0 = b - a, v1 = c - a, v2 = p - a; 
        float d00 = Dot(v0, v0); 
        float d01 = Dot(v0, v1); 
        float d11 = Dot(v1, v1); 
        float d20 = Dot(v2, v0); 
        float d21 = Dot(v2, v1); 
        float denom = d00 * d11 - d01 * d01; 
        v = (d11 * d20 - d01 * d21)/denom; 
        w = (d00 * d21 - d01 * d20)/denom; 
        u = 1.0f - v - w; 
    } 
    

    を、あなたは自分の与えられた値を三角測量する必要があります - 例えばあなたの例では、データポイント10,50,100に1つの三角形を、データポイント20,50,100に別の三角形を使用してください。

    スプラインは、曲率の連続性を保証する「スムーズ」補間に使用されます。

    0

    @schnaader私はあなたの重心の例をC#に変換しました。 提案は私の問題を解決しない、今私は温度を計算する追加のロジックが必要です。そして、3点以上では簡単な作業ではありません。

    C#例(Install-Package System.Numerics.Vectors

    Tuple<float, float, float> Barycentric(Vector2 p, Vector2 a, Vector2 b, Vector2 c) 
    { 
        Vector2 v0 = b - a, v1 = c - a, v2 = p - a; 
        float d00 = Vector2.Dot(v0, v0); 
        float d01 = Vector2.Dot(v0, v1); 
        float d11 = Vector2.Dot(v1, v1); 
        float d20 = Vector2.Dot(v2, v0); 
        float d21 = Vector2.Dot(v2, v1); 
    
        float denom = d00 * d11 - d01 * d01; 
        var v = (d11 * d20 - d01 * d21)/denom; 
        var w = (d00 * d21 - d01 * d20)/denom; 
        var u = 1.0f - v - w; 
        return new Tuple<float, float, float>(v, w, u); 
    }