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(); }
public EnvironmentSimulator(ConstantSet constants, Arm arm, HashSet <Food> food) { this.arm = arm; nodes = arm.Nodes.Concat(food.Cast <Node>()).ToArray(); IInfluence gravity = new GravityInfluence(constants); IInfluence buoyancy = new BuoyancyInfluence(constants); IInfluence friction = new SphericalFrictionInfluence(constants); // The spherical friction is added to food particles only foreach (Food f in food) { f.AddInfluence(friction); AddPart(f); } foreach (Node node in arm.Nodes) { node.AddInfluence(gravity); node.AddInfluence(buoyancy); IInfluence repulsion = new RepulsionInfluence(constants, node); foreach (Node j in nodes) { if (node != j) { j.AddInfluence(repulsion); } } // We add all of the ODE parts to this aggregate AddPart(node); } }
protected MuscleInfluence(ConstantSet constants, Node n1, Node n2, double width) { this.constants = constants; this.N1 = n1; this.N2 = n2; this.Width = width; this.action = 0; this.InitialLength = n1.Position.Subtract(n2.Position).Norm; this.Forces = new Dictionary <Node, Vector2D>(); // The constants are not set here, override this class to set the constants to the proper value this.ActiveConstant = 0; this.PassiveConstant = 0; this.DampingConstant = 0; }
/// <summary> /// Constructs a new compartment from four nodes </summary> /// <param name="dorsalNode"> Dorsal node </param> /// <param name="dorsalTransversalNode"> Dorsal transversal Node </param> /// <param name="ventralTransversalNode"> Ventral transversal node </param> /// <param name="ventralNode"> Ventral node </param> internal Compartment(ConstantSet constants, Node dorsalNode, Node dorsalTransversalNode, Node ventralTransversalNode, Node ventralNode) { this.constants = constants; this.d = dorsalNode; this.dt = dorsalTransversalNode; this.tv = ventralTransversalNode; this.v = ventralNode; nodes = new Node[] { dorsalNode, dorsalTransversalNode, ventralTransversalNode, ventralNode }; // Internal pressures pressure = new PressureInfluence(this.constants, this); foreach (Node n in nodes) { n.AddInfluence(pressure); } // Muscles dorsal = new LongitudinalMuscleInfluence(this.constants, dorsalNode, dorsalTransversalNode, dorsalTransversalNode.Position.Subtract(ventralTransversalNode.Position).Norm); dorsalNode.AddInfluence(dorsal); dorsalTransversalNode.AddInfluence(dorsal); transversal = new TransversalMuscleInfluence(this.constants, dorsalTransversalNode, ventralTransversalNode, dorsalTransversalNode.Position.Subtract(dorsalNode.Position).Norm); dorsalTransversalNode.AddInfluence(transversal); ventralTransversalNode.AddInfluence(transversal); ventral = new LongitudinalMuscleInfluence(this.constants, ventralTransversalNode, ventralNode, dorsalTransversalNode.Position.Subtract(ventralTransversalNode.Position).Norm); ventralTransversalNode.AddInfluence(ventral); ventralNode.AddInfluence(ventral); // Friction dorsalFriction = new AxialFrictionInfluence(this.constants, dorsalTransversalNode, dorsalNode); dorsalTransversalNode.AddInfluence(dorsalFriction); ventralFriction = new AxialFrictionInfluence(this.constants, ventralTransversalNode, ventralNode); ventralTransversalNode.AddInfluence(ventralFriction); pressureShapes = new List <object>(); ComputeArea(); desiredArea = area; }
/// <summary> /// The friction influence will only influence the target, the axial /// node serves only to give the orientation of the segment that /// gives the tangential direction for friction computation. </summary> /// <param name="target"> The node on which the friction will be computed. </param> /// <param name="axialNode"> A node that serves only to determine the orientation of the axis. </param> public AxialFrictionInfluence(ConstantSet constants, Node target, Node axialNode) { this.constants = constants; this.target = target; this.axialNode = axialNode; }
public BuoyancyInfluence(ConstantSet constants) { this.constants = constants; }
public SphericalFrictionInfluence(ConstantSet constants) { this.constants = constants; }
public GravityInfluence(ConstantSet constants) { this.constants = constants; }
public RepulsionInfluence(ConstantSet constants, Node source) { this.constants = constants; this.source = source; }
public PressureInfluence(ConstantSet constants, Compartment parent) { this.constants = constants; this.parent = parent; forces = new Dictionary <Node, Vector2D>(); }