我正在尝试在C#中为vector rejection实现一个函数。那就是:
我一直在尝试用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.
示例:
想象一下,矢量A是应用于沿地面移动的物体的力,矢量B是重力(垂直于地面)。当向量A应用于对象时,它移动的轨迹应该是垂直于重力的第三个向量,可以被认为是垂直于B的行进。这是从B中拒绝A。
答案 0 :(得分: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}
}
}
修改强>
如果您无法控制代码,可以将代码移到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}
}
}
当您对矢量代数规则进行编码时,投影和拒绝的编码与数学书籍中的公式相同。您可以使用Wolfram Alpha检查答案。
答案 1 :(得分: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
。