private void GenerateCubesButton_OnClick(object sender, RoutedEventArgs e) { if (Size > 256) { MessageBox.Show("Size must not be larger than 128", "Error", MessageBoxButton.OK, MessageBoxImage.Error); return; } Clear(); Noise.SetSeed(RandomHelpers.Random(0, int.MaxValue)); CubeItems = new CubeItem[Size, Size]; for (int x = 0; x < Size; x++) { for (int y = 0; y < Size; y++) { var noiseValue = Noise.GetValue(x, y).Map(-1, 1, 0, 1000); CubeItems[x, y] = new CubeItem() { IsFull = noiseValue > NoiseFilter }; } } DrawCubes(); }
// random utility, worth moving to Utilities.h? void RegenerateMap() { // regenerate map: clear and add random "rocks" _vehicle.Map.Clear(); DrawRandomClumpsOfRocksOnMap(_vehicle.Map); ClearCenterOfMap(_vehicle.Map); // draw fences for first two demo modes if (MapDriver.DemoSelect < 2) { DrawBoundaryFencesOnMap(_vehicle.Map); } // randomize path widths if (MapDriver.DemoSelect == 2) { int count = _vehicle.Path.PointCount; bool upstream = _vehicle.PathFollowDirection > 0; int entryIndex = upstream ? 1 : count - 1; int exitIndex = upstream ? count - 1 : 1; float lastExitRadius = _vehicle.Path.Radii[exitIndex]; for (int i = 1; i < count; i++) { _vehicle.Path.Radii[i] = RandomHelpers.Random(4, 19); } _vehicle.Path.Radii[entryIndex] = lastExitRadius; } // mark path-boundary map cells as obstacles // (when in path following demo and appropriate mode is set) if (_usePathFences && (MapDriver.DemoSelect == 2)) { DrawPathFencesOnMap(_vehicle.Map, _vehicle.Path); } }
private void RandomizeStartingPositionAndHeading() { // randomize position on a ring between inner and outer radii // centered around the home base float rRadius = RandomHelpers.Random(10, 50); Vector3 randomOnRing = Vector3Helpers.RandomUnitVectorOnXZPlane() * rRadius; Position = (Globals.HomeBaseCenter + randomOnRing); RandomizeHeadingOnXZPlane(); }
public void BoundedRandom() { const int LOWER = -17; const int UPPER = 24; var rand = RandomHelpers.Random(LOWER, UPPER); Assert.IsTrue(LOWER <= rand); Assert.IsTrue(UPPER >= rand); }
// xxx couldn't this be made more compact using localizePosition? /// <summary> /// Checks for intersection of the given spherical obstacle with a /// volume of "likely future vehicle positions": a cylinder along the /// current path, extending minTimeToCollision seconds along the /// forward axis from current position. /// /// If they intersect, a collision is imminent and this function returns /// a steering force pointing laterally away from the obstacle's center. /// /// Returns a zero vector if the obstacle is outside the cylinder /// </summary> /// <param name="v"></param> /// <param name="minTimeToCollision"></param> /// <returns></returns> public Vector3 SteerToAvoid(IVehicle v, float minTimeToCollision) { // Capsule x Sphere collision detection //http://www.altdev.co/2011/04/26/more-collision-detection-for-dummies/ var capStart = v.Position; var capEnd = v.PredictFuturePosition(minTimeToCollision); var alongCap = capEnd - capStart; var capLength = alongCap.Length(); //If the vehicle is going very slowly then simply test vehicle sphere against obstacle sphere if (capLength <= 0.05) { var distance = Vector3.Distance(Center, v.Position); if (distance < Radius + v.Radius) { return(v.Position - Center); } return(Vector3.Zero); } var capAxis = alongCap / capLength; //Project vector onto capsule axis var b = Utilities.Clamp(Vector3.Dot(Center - capStart, capAxis), 0, capLength); //Get point on axis (closest point to sphere center) var r = capStart + capAxis * b; //Get distance from circle center to closest point var dist = Vector3.Distance(Center, r); //Basic sphere sphere collision about the closest point var inCircle = dist < Radius + v.Radius; if (!inCircle) { return(Vector3.Zero); } //avoidance vector calculation Vector3 avoidance = Vector3Helpers.PerpendicularComponent(v.Position - Center, v.Forward); //if no avoidance was calculated this is because the vehicle is moving exactly forward towards the sphere, add in some random sideways deflection if (avoidance == Vector3.Zero) { avoidance = -v.Forward + v.Side * 0.01f * RandomHelpers.Random(); } avoidance = Vector3.Normalize(avoidance); avoidance *= v.MaxForce; avoidance += v.Forward * v.MaxForce * 0.75f; return(avoidance); }
// reset position private void RandomizeStartingPositionAndHeading() { // randomize position on a ring between inner and outer radii // centered around the home base const float INNER = 20; const float OUTER = 30; float radius = RandomHelpers.Random(INNER, OUTER); Vector3 randomOnRing = Vector3Helpers.RandomUnitVectorOnXZPlane() * radius; Position = (_wanderer.Position + randomOnRing); // randomize 2D heading RandomizeHeadingOnXZPlane(); }
public void ClipWithoutConeIsAlwaysWithoutCone() { for (int i = 0; i < 5000; i++) { var vector = Vector3Helpers.RandomUnitVector(); var basis = Vector3Helpers.RandomUnitVector(); var angle = RandomHelpers.Random(0.1f, PiOver2); var cosAngle = (float)Math.Cos(angle); var result = vector.LimitMinDeviationAngle(cosAngle, basis); var measuredAngle = (float)Math.Acos(Vector3.Dot(result, basis)); Assert.IsTrue(measuredAngle >= angle - 0.0001f); } }
public void Random() { // Arrange var hash = new Dictionary <string, object?> { { "Type", "Integer" }, { "Min", 1000 }, { "Max", 9999 } }; // Act var result = _sut.Random(hash); // Assert (result as int?).Should().BeInRange(1000, 9999); }
private static void AddOneObstacle() { if (_obstacleCount >= MAX_OBSTACLE_COUNT) { return; } // pick a random center and radius, // loop until no overlap with other obstacles and the home base //float r = 15; //Vector3 c = Vector3.Up * r * (-0.5f * maxObstacleCount + obstacleCount); float r = RandomHelpers.Random(0.5f, 2); Vector3 c = Vector3Helpers.RandomVectorInUnitRadiusSphere() * WORLD_RADIUS * 1.1f; // add new non-overlapping obstacle to registry AllObstacles.Add(new SphericalObstacle(r, c)); _obstacleCount++; }
// reset state public override void Reset() { base.Reset(); // reset the vehicle Speed = 0.0f; // speed along Forward direction. // Place me on my part of the field, looking at oponnents goal Position = new Vector3(_imTeamA ? RandomHelpers.Random() * 20 : -RandomHelpers.Random() * 20, 0, (RandomHelpers.Random() - 0.5f) * 20); if (_myID < 9) { Position = _imTeamA ? (Globals.PlayerPosition[_myID]) : (new Vector3(-Globals.PlayerPosition[_myID].X, Globals.PlayerPosition[_myID].Y, Globals.PlayerPosition[_myID].Z)); } _home = Position; if (_trail == null) { _trail = new Trail(10, 60); } _trail.Clear(); // prevent long streaks due to teleportation }
private void RandomizeStartingPositionAndHeading() { // randomize position on a ring between inner and outer radii // centered around the home base float rRadius = RandomHelpers.Random(Globals.MIN_START_RADIUS, Globals.MAX_START_RADIUS); Vector3 randomOnRing = Vector3Helpers.RandomUnitVectorOnXZPlane() * rRadius; Position = (Globals.HomeBaseCenter + randomOnRing); // are we are too close to an obstacle? if (MinDistanceToObstacle(Position) < Radius * 5) { // if so, retry the randomization (this recursive call may not return // if there is too little free space) RandomizeStartingPositionAndHeading(); } else { // otherwise, if the position is OK, randomize 2D heading RandomizeHeadingOnXZPlane(); } }
public static void AddOneObstacle(float radius) { // pick a random center and radius, // loop until no overlap with other obstacles and the home base float r; Vector3 c; float minClearance; float requiredClearance = Globals.Seeker.Radius * 4; // 2 x diameter do { r = RandomHelpers.Random(1.5f, 4); c = Vector3Helpers.RandomVectorOnUnitRadiusXZDisk() * Globals.MAX_START_RADIUS * 1.1f; minClearance = AllObstacles.Aggregate(float.MaxValue, (current, t) => TestOneObstacleOverlap(current, r, t.Radius, c, t.Center)); minClearance = TestOneObstacleOverlap(minClearance, r, radius - requiredClearance, c, Globals.HomeBaseCenter); }while (minClearance < requiredClearance); // add new non-overlapping obstacle to registry AllObstacles.Add(new SphericalObstacle(r, c)); ObstacleCount++; }
// reset all instance state public override void Reset() { // reset the vehicle base.Reset(); // initially stopped Speed = 0; // size of bounding sphere, for obstacle avoidance, etc. Radius = 0.5f; // width = 0.7, add 0.3 margin, take half // set the path for this Pedestrian to follow _path = Globals.GetTestPath(); // set initial position // (random point on path + random horizontal offset) float d = _path.TotalPathLength * RandomHelpers.Random(); float r = _path.Radius; Vector3 randomOffset = Vector3Helpers.RandomVectorOnUnitRadiusXZDisk() * r; Position = (_path.MapPathDistanceToPoint(d) + randomOffset); // randomize 2D heading RandomizeHeadingOnXZPlane(); // pick a random direction for path following (upstream or downstream) _pathDirection = RandomHelpers.Random() <= 0.5; // trail parameters: 3 seconds with 60 points along the trail _trail = new Trail(3, 60); // notify proximity database that our position has changed if (_proximityToken != null) { _proximityToken.UpdateForNewPosition(Position); } }
// compute combined steering force: move forward, avoid obstacles // or neighbors if needed, otherwise follow the path and wander private Vector3 DetermineCombinedSteering(float elapsedTime) { // move forward Vector3 steeringForce = Forward; // probability that a lower priority behavior will be given a // chance to "drive" even if a higher priority behavior might // otherwise be triggered. const float LEAK_THROUGH = 0.1f; // determine if obstacle avoidance is required Vector3 obstacleAvoidance = Vector3.Zero; if (LEAK_THROUGH < RandomHelpers.Random()) { const float O_TIME = 6; // minTimeToCollision = 6 seconds obstacleAvoidance = SteerToAvoidObstacles(O_TIME, Globals.Obstacles); } // if obstacle avoidance is needed, do it if (obstacleAvoidance != Vector3.Zero) { steeringForce += obstacleAvoidance; } else { // otherwise consider avoiding collisions with others Vector3 collisionAvoidance = Vector3.Zero; const float CA_LEAD_TIME = 3; // find all neighbors within maxRadius using proximity database // (radius is largest distance between vehicles traveling head-on // where a collision is possible within caLeadTime seconds.) float maxRadius = CA_LEAD_TIME * MaxSpeed * 2; _neighbors.Clear(); _proximityToken.FindNeighbors(Position, maxRadius, _neighbors); if (_neighbors.Count > 0 && LEAK_THROUGH < RandomHelpers.Random()) { collisionAvoidance = SteerToAvoidNeighbors(CA_LEAD_TIME, _neighbors) * 10; } // if collision avoidance is needed, do it if (collisionAvoidance != Vector3.Zero) { steeringForce += collisionAvoidance; } else { // add in wander component (according to user switch) if (Globals.WanderSwitch) { steeringForce += SteerForWander(elapsedTime); } // do (interactively) selected type of path following const float PF_LEAD_TIME = 3; Vector3 pathFollow = (Globals.UseDirectedPathFollowing ? SteerToFollowPath(_pathDirection, PF_LEAD_TIME, _path) : SteerToStayOnPath(PF_LEAD_TIME, _path)); // add in to steeringForce steeringForce += pathFollow * 0.5f; } } // return steering constrained to global XZ "ground" plane steeringForce.Y = 0; return(steeringForce); }