2014-11-16 2 views
2

Я пытаюсь реализовать функцию для vector rejection в C#. То есть:Векторная проекция/отказ в C#?

enter image description here

Я пытался кодировать эту формулу в C#, однако по какой-то причине он всегда возвращался к нулю. Это то, что у меня нет до сих пор:

private Vector3 Projection(Vector3 vectorA, Vector3 vectorB) { 
    Vector3 a2 = Vector3.Scale (Divide (Vector3.Scale (vectorA, vectorB), Vector3.Scale (vectorB, vectorB)), vectorB); 
    return a2; 
} 

private Vector3 Rejection(Vector3 vectorA, Vector3 vectorB) { 
    Vector3 a2 = vectorA - Projection(vectorA, vectorB); 
    return a2; 
} 

private Vector3 Divide(Vector3 a, Vector3 b) { 
    Vector3 c = new Vector3(); 
    c.x = a.x/b.x; 
    c.y = a.y/b.y; 
    c.z = a.z/b.z; 
    return c; 
} 

private void Example() { 
    Vector3 a = new Vector3 (5, 5, 0); 
    Vector3 b = new Vector3 (0, 10, 0); 
    Vector3 c = Rejection(a, b); // Returns (NaN, 0, NaN) 
} 

// The Vector3 class represents a 3D vector and it's x, y and z components are of float type. It's [scale method][3] multiplies two vectors component wise. 

Пример:

Представьте Вектор А является сила, приложенная к объекту, который перемещается по земле и вектор В является сила тяжести (которая перпендикулярна к земле) , Когда вектор А применяются к объекту траектория двигается должна быть третьим вектором, перпендикулярной к гравитации, который можно рассматривать как бегущую перпендикулярны B. Это является отказом от А из В.

enter image description here

+0

Вы можете опубликовать определение «Вектор» (особенно типы x, y, z) и определение «Масштаб»? Кроме того, какие параметры вы используете? Что он возвращается? Вы говорите, что он возвращает ноль, но он возвращает вектор так, что это невозможно. –

+0

Возможно, вы захотите отметить этот вопрос как уникальный для Unity, так как вы спрашиваете о функциональности класса Unity 'Vector3'. –

+0

Привет, я не понимал, что этот класс специфичен для Unity. Я могу использовать другой, но я помечаю его для Unity. – lisovaccaro

ответ

3

Обозначение a·b представляет собой vector dot product, а результат - скалярное значение.

Так что вам нужно, это код, как это:

public struct Vector3 
{ 
    public readonly double x, y, z; 
    public Vector3(double x, double y, double z) 
    { 
     this.x=x; 
     this.y=y; 
     this.z=z; 
    } 
    public double Dot(Vector3 other) 
    { 
     return x*other.x+y*other.y+z*other.z; 
    } 
    public Vector3 Scale(double factor) 
    { 
     return new Vector3(factor*x, factor*y, factor*z); 
    } 
    public Vector3 Add(Vector3 other) 
    { 
     return new Vector3(x+other.x, y+other.y, z+other.z); 
    } 
    public static Vector3 operator+(Vector3 a, Vector3 b) { return a.Add(b); } 
    public static Vector3 operator-(Vector3 a) { return a.Scale(-1); } 
    public static Vector3 operator-(Vector3 a, Vector3 b) { return a.Add(-b); } 
    public static Vector3 operator*(double f, Vector3 a) { return a.Scale(f); } 
    public static Vector3 operator/(Vector3 a, double d) { return a.Scale(1/d); } 
    public static double operator*(Vector3 a, Vector3 b) { return a.Dot(b); } 

    public Vector3 Projection(Vector3 other) 
    { 
     // (scalar/scalar)*(vector) = (vector) 
     return (other*this)/(other*other)*other; 
    } 
    public Vector3 Rejection(Vector3 other) 
    { 
     // (vector)-(vector) = (vector) 
     return this-Projection(other); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     var A=new Vector3(5, 5, 0); 
     var B=new Vector3(0, 10, 0); 
     var C=A.Rejection(B); 
     // C = { 5,0,0}, expected answer from math {5,5,0}-0.5*{0,10,0} 
    } 
} 

EDIT

Вы можете переместить код за пределы Vector3 класса, если вы не имеете никакого контроля над ним

// Vector3 defined elsewhere with .x, .y and .z fields 

class VectorAlgebra 
{ 
    public static Vector3 Subtract(Vector3 a, Vector3 b) 
    { 
     return new Vector3(a.x-b.x, a.y-b.y, a.z-b.z); 
    } 
    public static Vector3 Scale(float f, Vector3 a) 
    { 
     return new Vector3(f*a.x, f*a.y, f*a.z); 
    } 

    public static float Dot(Vector3 a, Vector3 b) 
    { 
     return (a.x*b.x)+(a.y*b.y)+(a.z*b.z); 
    } 

    public static Vector3 Projection(Vector3 a, Vector3 b) 
    { 
     return Scale(Dot(a, b)/Dot(b, b), b); 
    } 
    public static Vector3 Rejection(Vector3 a, Vector3 b) 
    { 
     return Subtract(a, Projection(a, b)); 
    } 

    static void Main(string[] args) 
    { 
     var A=new Vector3(5, 5, 0); 
     var B=new Vector3(0, 10, 0); 
     var C=Rejection(A, B); 
     // C = { 5,0,0}, expected answer from math {5,5,0}-0.5*{0,10,0} 
    } 
} 

Престола когда вы кодируете правила векторной алгебры, кодирование для Проекции и Отклонения становится идентичным формулировке в математике boo кс. Вы можете проверить ответ Wolfram Alpha.

+0

Из [документации] (http://docs.unity3d.com/ScriptReference/Vector3.Scale.html), похоже, 'Scale '** является ** точечным продуктом, хотя я согласен, что это нечетная терминология. –

+0

Спасибо, ты спасатель жизни. Также я перемещал код вне Vector3, и вы спасли мне много работы. Я отредактирую ответ с тем, что я использовал в конце. – lisovaccaro

0

Хорошо, теперь у нас есть некоторые цифры, давайте сломаем шаги с

Vector3.Scale (Divide (Vector3.Scale (vectorA, vectorB), Vector3.Scale (vectorB, vectorB)), vectorB); 

является

var numerator = Vector3.Scale (vectorA, vectorB); 
var denominator = Vector3.Scale (vectorB, vectorB); 
var divided = Divide(numerator, denominator); 
var result = Vector3.Scale(divided, vectorB); 

, который работает через ваш номера будут

vectorA = (5,5,0) 
vectorB = (0,10,0) 
numerator = (0,50,0) 
denominator = (0,100,0) 
divided = (NaN,.5,NaN) <- since you can't divide by zero 
result = (NaN,5,NaN) 

Не знаете, почему вы получаете 0 для второго измерения вместо 5 (опечатка? какой-то тип кастинга?), но, надеюсь, это объясняет, почему у вас появилось NaN.

+0

Фокус в том, что 'Scale()' возвращает скаляр, и нет необходимости в векторном делении с 'Divide()'. – ja72

+0

@ ja72 Это не то, что показывает документация для «Масштаба» - в документах он возвращает вектор –

+0

. В другом комментарии вы упомянули «Масштаб» - это точечный продукт. Он не может быть точечным продуктом и возвращать вектор. – ja72

Смежные вопросы