public double Dot(VectorND v) { double dot = 0; for (int i = 0; i < this.Dimension; i++) { dot += this.X[i] * v.X[i]; } return(dot); }
/// <summary> /// 3D -> 2D projection. /// </summary> public VectorND ProjectTo2D(double cameraDist) { double denominator = cameraDist - X[2]; if (Tolerance.Zero(denominator)) { denominator = 0; } // Make points with a negative denominator invalid. if (denominator < 0) { denominator = 0; } VectorND result = new VectorND(new double[] { X[0] * cameraDist / denominator, X[1] * cameraDist / denominator, 0, 0 }); return(result); }
public GraphNode( VectorND pos, VectorND vel ) { Position = pos; Velocity = vel; Lock = false; }
private void UpdatePositionAndVelocity( GraphNode node, VectorND acceleration ) { if( node.Lock ) return; VectorND position = node.Position; VectorND velocity = node.Velocity; //if( position.IsOrigin ) // return; // Leapfrog method. double timeStep = 1; velocity += acceleration * timeStep; velocity *= .5; // Damping. position += velocity * timeStep; //position.Normalize(); position *= 5; //if( position.MagSquared > 1 ) //{ // position.Normalize(); // velocity = new VectorND( 3 ); //} node.Position = position; node.Velocity = velocity; //node.Acceleration = acceleration; Any reason to store this? }
private VectorND[] CalcAccelerations() { int count = Graph.Nodes.Count; VectorND[] accelerations = new VectorND[count]; for( int i = 0; i < count; i++ ) accelerations[i] = new VectorND( m_dim ); bool nodeRepulse = !Tolerance.Zero( NodeRepulsion ); for( int i = 0; i < count; i++ ) for( int j = i + 1; j < count; j++ ) { if( nodeRepulse ) { VectorND nodeForce = CalculateForce( Graph.Nodes[i], Graph.Nodes[j], NodeRepulsion, square: true ); accelerations[i] -= nodeForce; // Repulsive. accelerations[j] += nodeForce; } if( Graph.Connected( i, j ) ) { VectorND edgeForce = CalculateForce( Graph.Nodes[i], Graph.Nodes[j], EdgeAttraction, square: false ); accelerations[i] += edgeForce; // Attractive. accelerations[j] -= edgeForce; } } if( Tolerance.Zero( EdgeRepulsion ) ) return accelerations; count = Graph.Edges.Count; for( int i = 0; i < count; i++ ) for( int j = i + 1; j < count; j++ ) { // Rather than mess with torques and doing this "right" (like it was two charged rod segments), // We'll calculate the effect on the two COMs, and give half the force to each node. int n1 = Graph.Edges[i].V1; int n2 = Graph.Edges[i].V2; int n3 = Graph.Edges[j].V1; int n4 = Graph.Edges[j].V2; GraphNode center1 = new GraphNode( ( Graph.Nodes[n1].Position + Graph.Nodes[n2].Position ) / 2, new VectorND( m_dim ) ); GraphNode center2 = new GraphNode( ( Graph.Nodes[n3].Position + Graph.Nodes[n4].Position ) / 2, new VectorND( m_dim ) ); VectorND force = CalculateForce( center1, center2, EdgeRepulsion, square: true ) / 2; accelerations[n1] -= force; accelerations[n2] -= force; accelerations[n3] += force; accelerations[n3] += force; } return accelerations; }
/// <summary> /// 4D -> 3D projection. /// </summary> public VectorND ProjectTo3D( double cameraDist ) { double denominator = cameraDist - X[3]; if( Tolerance.Zero( denominator ) ) denominator = 0; // Make points with a negative denominator invalid. if( denominator < 0 ) denominator = 0; VectorND result = new VectorND( new double[] { X[0] * cameraDist / denominator, X[1] * cameraDist / denominator, X[2] * cameraDist / denominator, 0 }); return result; }
public double Dot( VectorND v ) { double dot = 0; for( int i = 0; i < this.Dimension; i++ ) dot += this.X[i] * v.X[i]; return dot; }
public double Dist( VectorND v ) { return ( this - v ).Abs; }
public double Dist(VectorND v) { return((this - v).Abs); }
/// <summary> /// Rotate a vector with this matrix. /// </summary> public VectorND RotateVector( VectorND input ) { VectorND result = new VectorND( 4 ); VectorND copy = input.Clone(); for( int i = 0; i < 4; i++ ) { result.X[i] = copy.X[0] * this[i, 0] + copy.X[1] * this[i, 1] + copy.X[2] * this[i, 2] + copy.X[3] * this[i, 3]; } return result; }
/// <summary> /// Rotate a vector with this matrix. /// </summary> public Vector3D RotateVector( Vector3D input ) { VectorND result = new VectorND( 4 ); VectorND copy = new VectorND( new double[] { input.X, input.Y, input.Z, input.W } ); for( int i = 0; i < 4; i++ ) { result.X[i] = copy.X[0] * this[i, 0] + copy.X[1] * this[i, 1] + copy.X[2] * this[i, 2] + copy.X[3] * this[i, 3]; } return new Vector3D( result.X[0], result.X[1], result.X[2], result.X[3] ); }
/// <summary> /// VectorNDs are assumed to be 4D. /// </summary> public VectorND Pixel( VectorND point ) { Vector3D result = Pixel( new Vector3D( point.X[0], point.X[1], point.X[2] ) ); return new VectorND( new double[] { result.X, result.Y, result.Z, 0 } ); }
// Minkowski normalization. private static VectorND MinkowskiNormalize( VectorND v ) { double mag2 = MinkowskiInnerProduct( v, v ); double abs = mag2 < 0 ? Math.Sqrt( -mag2 ) : Math.Sqrt( mag2 ); v.Divide( abs ); return v; }
// Minkowski inner product. private static double MinkowskiInnerProduct( VectorND v1, VectorND v2 ) { double inner = -v1.X[0] * v2.X[0]; for( int i = 1; i < v1.Dimension; i++ ) inner += v1.X[i] * v2.X[i]; return inner; }
public static Vector3D HyperboloidToBall( VectorND hyperboloidPoint ) { double t = hyperboloidPoint.X[0]; return new Vector3D( hyperboloidPoint.X[1] / ( 1 + t ), hyperboloidPoint.X[2] / ( 1 + t ), hyperboloidPoint.X[3] / ( 1 + t ) ); }