// =============================================================================================== // method to display output to grasshopper with some optimization in conversion // =============================================================================================== public void DisplayToGrasshopper() { if (Containment[0].Label == 's') { _container = (SurfaceContainment)Containment[0]; var nu = NumberOperations.remap(XMin, XMax, _container.Surface.Domain(0).T0, _container.Surface.Domain(0).T1, Position.X); var nv = NumberOperations.remap(YMin, YMax, _container.Surface.Domain(1).T0, _container.Surface.Domain(1).T1, Position.Y); var vu = NumberOperations.remap(XMin, XMax, _container.Surface.Domain(0).T0, _container.Surface.Domain(0).T1, Velocity.X); var vv = NumberOperations.remap(YMin, YMax, _container.Surface.Domain(1).T0, _container.Surface.Domain(1).T1, Velocity.Y); GHPosition = new GH_Point(_container.Surface.PointAt(nu, nv)); GHVelocity = new GH_Vector(new Vector3d(_container.Surface.PointAt(vu, vv))); } else { GHPosition = new GH_Point(Position); GHVelocity = new GH_Vector(Velocity); } }
// =============================================================================================== // method to add behaviours to agents // =============================================================================================== public void ComputeDesiredVelocity(List <IFlockAgent> neighbours) { // First, reset the desired velocity to 0 _desiredVelocity = new Vector3d(0.0, 0.0, 0.0); // Pull the agent back if it gets out of the bounding box foreach (var icontainment in Containment) { _desiredVelocity += icontainment.DesiredVector(Position, _desiredVelocity); } // If there are no neighbours nearby, the agent will maintain its veloctiy, // else it will perform the "alignment", "cohension" and "separation" behaviours if (neighbours.Count == 0) { _desiredVelocity += Velocity; // maintain the current velocity } else { // ------------------------------------------------------------------------------- // "Alignment" behavior // ------------------------------------------------------------------------------- _desiredVelocity += AgentBehaviours.Alignment(neighbours, _desiredVelocity, FlockSystem); // ------------------------------------------------------------------------------- // "Cohesion" behavior // ------------------------------------------------------------------------------- _desiredVelocity += AgentBehaviours.Cohesion(neighbours, Position, _desiredVelocity, FlockSystem); // ------------------------------------------------------------------------------- // "Separation" behavior // ------------------------------------------------------------------------------- _desiredVelocity += AgentBehaviours.Separation(neighbours, Position, _desiredVelocity, FlockSystem); } // ------------------------------------------------------------------------------- //// Interactionbehaviours // ------------------------------------------------------------------------------- foreach (var interaction in Interactions) { switch (interaction.BehaviourType) { //======================================================================================= //if interaction is repeller case BehaviourType.Repeller: if (Containment[0].Label == 's') { _container = (SurfaceContainment)Containment[0]; foreach (var repeller in interaction.Circles) { // Remap repellers double u; double v; _container.Surface.ClosestPoint(repeller.Center, out u, out v); var nu = NumberOperations.remap(SrfBoudningBox.Min.X, SrfBoudningBox.Max.X, XMin, XMax, u); var nv = NumberOperations.remap(SrfBoudningBox.Min.Y, SrfBoudningBox.Max.Y, YMin, YMax, v); Point3d remappedCenter = new Point3d(nu, nv, 0); Circle remappedCircle = new Circle(remappedCenter, repeller.Radius); _surfaceRepller.Add(remappedCircle); } FlockSystem.Repellers = _surfaceRepller; } else { FlockSystem.Repellers = interaction.Circles; } break; //======================================================================================= //if interaction is Attractor case BehaviourType.Attractor: if (Containment[0].Label == 's') { _container = (SurfaceContainment)Containment[0]; foreach (var attractor in interaction.Circles) { // Remap Attractors double u; double v; _container.Surface.ClosestPoint(attractor.Center, out u, out v); var nu = NumberOperations.remap(SrfBoudningBox.Min.X, SrfBoudningBox.Max.X, XMin, XMax, u); var nv = NumberOperations.remap(SrfBoudningBox.Min.Y, SrfBoudningBox.Max.Y, YMin, YMax, v); Point3d remappedCenter = new Point3d(nu, nv, 0); Circle remappedCircle = new Circle(remappedCenter, attractor.Radius); _surfaceAttractors.Add(remappedCircle); } FlockSystem.Attractors = _surfaceAttractors; } else { FlockSystem.Attractors = interaction.Circles; } var closestPoint = PointOperations.ClosestPoints(Position, FlockSystem.Attractors.Select(p => p.Center).ToList(), 1); interaction.ClosestPoint = closestPoint[0]; break; //======================================================================================= //if interaction is Attractor curve case BehaviourType.AttractorCurve: if (Containment[0].Label == 's') { //getting curve data: points and degree _container = (SurfaceContainment)Containment[0]; var interactionAttractorCurve = (AttractorCurve)interaction; var attractorcurve = interactionAttractorCurve.Curves[0].ToNurbsCurve(); var controlpoints = attractorcurve.Points; var degree = attractorcurve.Degree; foreach (var controlpoint in controlpoints) { double u; double v; _container.Surface.ClosestPoint(controlpoint.Location, out u, out v); var nu = NumberOperations.remap(_container.Surface.Domain(0).T0, _container.Surface.Domain(0).T1, XMin, XMax, u); var nv = NumberOperations.remap(_container.Surface.Domain(1).T0, _container.Surface.Domain(1).T1, YMin, YMax, v); Point3d remappedControlPoint = new Point3d(nu, nv, 0); _remappedPoints.Add(remappedControlPoint); } var remappedCurve = Curve.CreateControlPointCurve(_remappedPoints, degree); _remappedCurves.Add(remappedCurve); FlockSystem.AttractorCurves = _remappedCurves; } else { FlockSystem.AttractorCurves = interaction.Curves; } var attractorCast = (AttractorCurve)interaction; FlockSystem.AttractorCurvesSwitch = attractorCast.AttractorCurveSwitch; //FlockSystem.AttractorCurves[0].ClosestPoint(StartPosition, out t); //var curveClosestPoint = FlockSystem.AttractorCurves[0].PointAt(t); Point3d curveClosestPoint; if (FlockSystem.AttractorCurvesSwitch) { List <Point3d> curveClosestPoints = new List <Point3d>(); foreach (var attractorCurve in FlockSystem.AttractorCurves) { double t; attractorCurve.ClosestPoint(StartPosition, out t); curveClosestPoints.Add(attractorCurve.PointAt(t)); } curveClosestPoint = PointOperations.ClosestPoints(StartPosition, curveClosestPoints, 1)[0]; } else { List <Point3d> curveClosestPoints = new List <Point3d>(); foreach (var attractorCurve in FlockSystem.AttractorCurves) { double t; attractorCurve.ClosestPoint(Position, out t); curveClosestPoints.Add(attractorCurve.PointAt(t)); } curveClosestPoint = PointOperations.ClosestPoints(Position, curveClosestPoints, 1)[0]; } interaction.ClosestPoint = curveClosestPoint; break; //======================================================================================= //if interaction is Repeller curve case BehaviourType.RepellerCurve: if (Containment[0].Label == 's') { //getting curve data: points and degree _container = (SurfaceContainment)Containment[0]; var interactionRepellerCurve = (RepellerCurve)interaction; var attractorcurve = interactionRepellerCurve.Curves[0].ToNurbsCurve(); var controlpoints = attractorcurve.Points; var degree = attractorcurve.Degree; foreach (var controlpoint in controlpoints) { double u; double v; _container.Surface.ClosestPoint(controlpoint.Location, out u, out v); var nu = NumberOperations.remap(_container.Surface.Domain(0).T0, _container.Surface.Domain(0).T1, XMin, XMax, u); var nv = NumberOperations.remap(_container.Surface.Domain(1).T0, _container.Surface.Domain(1).T1, YMin, YMax, v); Point3d remappedControlPoint = new Point3d(nu, nv, 0); _remappedPoints.Add(remappedControlPoint); } var remappedCurve = Curve.CreateControlPointCurve(_remappedPoints, degree); _remappedCurves.Add(remappedCurve); FlockSystem.RepllerCurves = _remappedCurves; } else { FlockSystem.RepllerCurves = interaction.Curves; } //FlockSystem.RepllerCurves[0].ClosestPoint(Position, out t); //var repellerCurveClosestPoint = FlockSystem.RepllerCurves[0].PointAt(t); List <Point3d> repellerCurveClosestPoints = new List <Point3d>(); foreach (var repellerCurve in FlockSystem.RepllerCurves) { double t; repellerCurve.ClosestPoint(Position, out t); repellerCurveClosestPoints.Add(repellerCurve.PointAt(t)); } var repellerCurveClosestPoint = PointOperations.ClosestPoints(Position, repellerCurveClosestPoints, 1)[0]; interaction.ClosestPoint = repellerCurveClosestPoint; break; //======================================================================================= //if interaction is Follow Points case BehaviourType.FollowPoints: FlockSystem.FollowAttractors = interaction.Circles; break; //======================================================================================= //if interaction is follow curve case BehaviourType.FollowCurve: FlockSystem.FollowCurveAttractors = interaction.Circles; break; //======================================================================================= //if interaction is Wind case BehaviourType.Wind: FlockSystem.Wind = interaction.WindVec; break; } interaction.Position = Position; interaction.FlockSystem = FlockSystem; interaction.DesiredVelocity = _desiredVelocity; _desiredVelocity += interaction.ComputeDesiredVelocity(); } }