internal Arm(ConstantSet constants, ArmSpec spec) { IList <NodePairSpec> nodePairs = spec.NodePair; NodeSpec upperFirstSpec = nodePairs[0].Upper; NodeSpec lowerFirstSpec = nodePairs[0].Lower; DominatedNode lowerFirst = new DominatedNode(lowerFirstSpec.Mass, Vector2D.FromDuple(lowerFirstSpec.Position), Vector2D.FromDuple(lowerFirstSpec.Velocity)); Node upperFirst = new RotationDominantNode(upperFirstSpec.Mass, Vector2D.FromDuple(upperFirstSpec.Position), Vector2D.FromDuple(upperFirstSpec.Velocity), lowerFirst); UpperNodes = Enumerable .Repeat(upperFirst, 1) .Concat(nodePairs.Skip(1).Select(np => new Node(np.Upper))) .ToArray(); LowerNodes = Enumerable .Repeat(lowerFirst as Node, 1) .Concat(nodePairs.Skip(1).Select(np => new Node(np.Lower))) .ToArray(); Nodes = UpperNodes.Concat(LowerNodes).ToArray(); Compartments = UpperNodes .Select((node, index) => (index == 0) ? null : new Compartment(constants, UpperNodes[index - 1], UpperNodes[index], LowerNodes[index], LowerNodes[index - 1])) .Skip(1) .ToArray(); }
/// <summary> /// Constructs a node constrained to rotate about a center of rotation /// determined as the midpoint between the initial position and the initial /// position of the dominated node. /// </summary> /// <param name="initialPosition"> </param> /// <param name="initialVelocity"> </param> /// <param name="other"> /// The dominated node that will stay at 180 degrees... </param> public RotationDominantNode(double mass, Vector2D initialPosition, Vector2D initialVelocity, DominatedNode otherNode) : base(mass, initialPosition, initialVelocity) { other = otherNode; center = initialPosition.Add(otherNode.Position).Scale(0.5); Vector2D fromCenter = initialPosition.Subtract(center); radius = fromCenter.Norm; angle = Math.Atan2(fromCenter.PositionY, fromCenter.PositionX); angularVelocity = 0; }