Classe vettoriale C # - Decisione del progetto di interpolazione

2

Attualmente sto codificando una classe Vector in C # e sto arrivando al punto, dove devo capire, come voglio implementare una funzione / metodo per interpolare tra due vettori. La (ovvia) e anche la mia prima soluzione è stata semplicemente implementarla come metodo nella stessa classe vettoriale:

public class Vector3D
{
    public static Vector3D LinearInterpolate(Vector3D vector1,
        Vector3D vector2, double factor) { ... }

    public Vector3D LinearInterpolate(Vector3D other, double factor { ... }
}

(Ho deciso di offrire sia un metodo statico con due vettori come parametri che uno non statico, con un solo vettore come parametro)

Ma poi ho avuto l'idea di usare i metodi di estensione (definiti in una classe separata chiamata per esempio Interpolation per esempio), poiché l'interpolazione non è realmente limitata ai soli vettori. Quindi questo potrebbe essere un altro approccio:

public class Vector3D { ... }

public static class Interpolation
{
    public static Vector3D LinearInterpolate(this Vector3D vector,
        Vector3D other, double factor) { ... }
}

Ed ecco un esempio che mostra come si utilizzerebbero le diverse implementazioni:

{
    var vec1 = new Vector3D(5, 3, 1);
    var vec2 = new Vector3D(4, 2, 0);
    Vector3D vec3;

    vec3 = vec1.LinearInterpolate(vec2, 0.5); //1
    vec3 = Vector3D.LinearInterpolate(vec1, vec2, 0.5); //2

    //or with extension-methods

    vec3 = vec1.LinearInterpolate(vec2, 0.5); //3 (same as 1)
    vec3 = Interpolation.LinearInterpolation(vec1, vec2,
    0.5); //4
}

Non posso davvero decidere quale sia il design preferibile. Esiste una regola empirica su come implementare metodi / funzioni simili a quella sopra o è piuttosto una questione di preferenza? Mi piacerebbe davvero sentire le tue opinioni su cosa è meglio e - se possibile - perché.

    
posta Benjamin Rickels 10.11.2013 - 20:45
fonte

3 risposte

0

Forse sono venuto da Java, ma non mi piacciono i metodi di estensione a meno che non ci sia una buona ragione per farlo.

Se si desidera riutilizzare il codice operazione, la soluzione dovrebbe essere composizione. Crea un Interpolator che operi su un IEnumerable<double> (sfortunatamente, sembra che C # non abbia un equivalente a java.lang.Number , quindi non puoi rendere facilmente la classe generica). Non penso che sia una cattiva idea che anche la tua classe Vector lo implementa.

Per i punti bonus, rendi la classe un'interfaccia che definisce l'operazione e inietta un'istanza dell'interfaccia nell'oggetto, così puoi cambiare l'implementazione (o anche usare altri tipi di interpolazioni, se corrispondono alla firma del metodo) a farà.

    
risposta data 11.11.2013 - 00:26
fonte
0

Non usare classi statiche, metodi statici (inclusi i metodi di estensione) a meno che non ne abbia realmente bisogno (forse a causa del codice legacy o perché estendi un oggetto framework .Net).

Una spiegazione approfondita del perché la staticità è cattiva può essere trovata qui .

Per la tua classe Vector3, perché non scrivi semplicemente una classe (non statica)?

public interface ILinearInterpolation
{
     void Interpolate(Vector3 a, Vector3 b, double factor);        
}

Ora puoi scrivere un'implementazione su quell'interfaccia.

L'alternativa è di rendere Interpolate un metodo membro, ma dovresti cercare di mantenere l'interfaccia di classe semplice e piccola. Ora, sono d'accordo sul fatto che le classi Vector e Matrix sono un po 'un'eccezione, perché hanno un insieme di caratteristiche intrinseche più grandi rispetto alla maggior parte delle altre classi, poiché ci sono molte cose matematiche di cui potresti aver bisogno che un vettore dovrebbe essere in grado di fare; hai citato Normalize () come esempio nei commenti. Tuttavia, sento che l'Interpole dovrebbe essere nella sua stessa classe.

    
risposta data 12.11.2013 - 14:09
fonte
0

Vorrei utilizzare l'interfaccia e i generici (Vector2, Vector4 ecc. dovrebbe essere in grado di utilizzare la stessa implementazione) per la classe di implementazione dell'interpolazione e quindi aggiungere un metodo di estensione per rendere l'uso più pulito.

public class Vector3
{
    //Implementation
}

public interface IInterpolation<T>
{
    T Interpolate(T first, T second, double factor);
}

public class LinearInterpolation<T> : IInterpolation<T>
{
    T Interpolate(T first, T second, double factor)
    {
        return first + ((second - first) * t);
    }
}

public static Vector3Helper
{
    public static Vector3 LinearInterpolation(this Vector3 vector, Vector3 other, double factor)
    {
        var interpolation = new LinearInterpolation<Vector3>()
        return interpolation.Interpolate(vec1, vec2, 0.5);
    }
}

Utilizzo:

Vector3 vec1 = new Vector3(1, 1, 2);
Vector3 vec2 = new Vector3(3, 1, 2);

var interpolation = new LinearInterpolation<Vector3>()
var result interpolation.Interpolate(vec1, vec2, 0.5);

o con il metodo di estensione:

var result = vec1.LinearInterpolation(vec2 0.5);
    
risposta data 12.11.2013 - 15:19
fonte

Leggi altre domande sui tag