private static UtilityNewt.ObjectMassBreakdownSet GetMassBreakdown_Trapazoid(Point[] verticies, Vector3D size, double cellSize, bool isRight) { if (verticies.Length != 4) { throw new ApplicationException("There should be exactly 4 verticies passed in: " + verticies.Length.ToString()); } double base1 = (verticies[2].X - verticies[3].X) * size.X; // the verticies are built counter clockwise, starting at the lower left corner double base2 = (verticies[1].X - verticies[0].X) * size.X; double height = (verticies[2].Y - verticies[1].Y) * size.Y; List<Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>> items = new List<Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>>(); if (isRight) { // Rectangle double rectBase = base1; var rectangle = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, new Vector3D(rectBase, height, size.Z), cellSize); items.Add(new Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(rectangle, new Vector3D((base1 * .5d) - (base2 * .5d), 0d, 0d).ToPoint(), Quaternion.Identity, rectBase * height)); // Triangle double triangleBase = base2 - base1; var triangle = GetMassBreakdown_Triangle(new Vector3D(triangleBase, height, size.Z), cellSize, true); items.Add(new Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, new Vector3D(base1 * .5d, 0d, 0d) + triangle.Item2.ToPoint(), Quaternion.Identity, triangleBase * height * .5d)); } else { // Rectangle double rectBase = base1; var rectangle = UtilityNewt.GetMassBreakdown(UtilityNewt.ObjectBreakdownType.Box, UtilityNewt.MassDistribution.Uniform, new Vector3D(rectBase, height, size.Z), cellSize); items.Add(new Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(rectangle, new Vector3D(0d, 0d, 0d).ToPoint(), Quaternion.Identity, rectBase * height)); // Triangle - right double triangleBase = (base2 - base1) * .5d; var triangle = GetMassBreakdown_Triangle(new Vector3D(triangleBase, height, size.Z), cellSize, true); Vector3D triangleOffset = new Vector3D((rectBase * .5d) + (triangleBase * .5d), 0d, 0d) + triangle.Item2; double triangleArea = triangleBase * height * .5d; items.Add(new Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, triangleOffset.ToPoint(), Quaternion.Identity, triangleArea)); // Triangle - left triangleOffset = new Vector3D(triangleOffset.X * -1d, triangleOffset.Y, triangleOffset.Z); Quaternion triangleOrientation = new Quaternion(new Vector3D(0, 1, 0), 180d); items.Add(new Tuple<UtilityNewt.ObjectMassBreakdown, Point3D, Quaternion, double>(triangle.Item1, triangleOffset.ToPoint(), triangleOrientation, triangleArea)); } // Exit Function return UtilityNewt.Combine(items.ToArray()); }
private void ChangeSwarmBots(SwarmFormation formation) { ChangeSwarmBotsSprtRemoveAll(); if (formation == SwarmFormation.None) { _swarmbotFormation = SwarmFormation.None; return; } double startAngle, stepAngle; // 0 is straight in front of the ship int numBots; double distanceMult; switch (formation) { case SwarmFormation.AllFront: #region AllFront startAngle = 0d; stepAngle = 360d; //numBots = 20; numBots = _numSwarmbots; distanceMult = 8d; #endregion break; case SwarmFormation.AllRear: #region AllRear startAngle = 180d; stepAngle = 360d; //numBots = 20; numBots = _numSwarmbots; distanceMult = 8d; #endregion break; case SwarmFormation.Triangle: #region Triangle startAngle = 0d; stepAngle = 120d; //numBots = 10; numBots = _numSwarmbots / 3; if (numBots % 3 != 0 || numBots == 0) { numBots++; } distanceMult = 9d; #endregion break; case SwarmFormation.ReverseTriangle: #region ReverseTriangle startAngle = 180d; stepAngle = 120d; //numBots = 10; numBots = _numSwarmbots / 3; if (numBots % 3 != 0 || numBots == 0) { numBots++; } distanceMult = 9d; #endregion break; case SwarmFormation.Pentagon: #region Pentagon startAngle = 0d; stepAngle = 72d; //numBots = 7; numBots = _numSwarmbots / 5; if (numBots % 5 != 0 || numBots == 0) { numBots++; } distanceMult = 9d; #endregion break; case SwarmFormation.ReversePentagon: #region ReversePentagon startAngle = 180d; stepAngle = 72d; //numBots = 7; numBots = _numSwarmbots / 5; if (numBots % 5 != 0 || numBots == 0) { numBots++; } distanceMult = 9d; #endregion break; case SwarmFormation.SurroundShip: #region SurroundShip startAngle = 0d; stepAngle = 360d; //numBots = 30; numBots = _numSwarmbots; distanceMult = 0d; #endregion break; default: throw new ApplicationException("Unknown SwarmFormation: " + formation.ToString()); } // Figure out how far away from the ship the bots should be double chaseOffsetDistance = (_radiusX + _radiusY) / 2d; chaseOffsetDistance *= distanceMult; // Build the swarms double angle = startAngle; while (angle < startAngle + 360d) { Vector3D chasePoint = new Vector3D(0, chaseOffsetDistance, 0); chasePoint = chasePoint.GetRotatedVector(new Vector3D(0, 0, 1), angle); _swarmBots.Add(ChangeSwarmBotsSprtSwarm(numBots, chasePoint)); _swarmbotChasePoints.Add(chasePoint.ToPoint()); PointVisualizer chasePointSprite = new PointVisualizer(_map.Viewport, _sharedVisuals); chasePointSprite.PositionRadius = .1d; chasePointSprite.VelocityAccelerationLengthMultiplier = .05d; chasePointSprite.ShowPosition = _showDebugVisuals; chasePointSprite.ShowVelocity = _showDebugVisuals; chasePointSprite.ShowAcceleration = _showDebugVisuals && DEBUGSHOWSACCELERATION; _swarmbotChasePointSprites.Add(chasePointSprite); angle += stepAngle; } _swarmbotFormation = formation; }
private void CreateSpaceStations() { const double ZMIN = -20; const double ZMAX = -12; double xyCoord = _boundryMax.X * STATION_BOUNDRY_PERCENT; double zCoord = StaticRandom.NextDouble(ZMIN, ZMAX); double minDistanceBetweenStationsSquared = 200d * 200d; #region clear the old if (_stations != null) { foreach (var station in _stations) { _map.RemoveItem(station); } } _currentlyOverStation = null; _stations = null; #endregion List<SpaceStation2D> stations = new List<SpaceStation2D>(); #region Home Station // Make one right next to the player at startup Point3D homeLocation = Math3D.GetRandomVector_Circular_Shell(12).ToPoint(); stations.Add(CreateSpaceStations_Build(new Point3D(homeLocation.X, homeLocation.Y, zCoord))); #endregion // Make a few more for (int cntr = 0; cntr < 4; cntr++) { // Come up with a position that isn't too close to any other station Vector3D position = new Vector3D(); while (true) { #region Figure out position position = Math3D.GetRandomVector_Circular(xyCoord); position.Z = StaticRandom.NextDouble(ZMIN, ZMAX); // See if this is too close to an existing station bool isTooClose = false; foreach (SpaceStation station in stations) { Vector3D offset = position - station.PositionWorld.ToVector(); if (offset.LengthSquared < minDistanceBetweenStationsSquared) { isTooClose = true; break; } } if (!isTooClose) { break; } #endregion } stations.Add(CreateSpaceStations_Build(position.ToPoint())); } _stations = stations.ToArray(); }
/// <summary> /// Calculates the angle and updates the arc according to the specifed vectors. /// </summary> /// <param name="start">The vector of the starting point.</param> /// <param name="middle">The vector of the middle point.</param> /// <param name="end">The vector of the end point.</param> /// <param name="desiredRadius">The desired arc radius.</param> public void Update(Vector3D start, Vector3D middle, Vector3D end, double desiredRadius = 0) { _vector1 = middle - start; _vector2 = middle - end; if (desiredRadius == 0) { desiredRadius = Math.Min(_vector1.Length, _vector2.Length); } _vector1.Normalize(); _vector2.Normalize(); _angle = Vector3D.AngleBetween(_vector1, _vector2); start = middle - desiredRadius * _vector1; end = middle - desiredRadius * _vector2; line1.Point = middle.ToPoint(); line2.Point = start.ToPoint(); angleFigure.StartPoint = end.ToPoint(); arc.IsLargeArc = _angle > 180.0; arc.Point = end.ToPoint(); arc.Size = new Size(desiredRadius, desiredRadius); }
private void Brain_Flocking_ChasePoint() { // Calculate the center of position of the flock //TODO: Have a vision limit #region Direction to center flock Vector3D centerPosition = new Vector3D(0, 0, 0); foreach (SwarmBot1 bot in _otherBots) { centerPosition += bot.PhysicsBody.PositionToWorld(bot.PhysicsBody.CenterOfMass).ToVector(); } if (_otherBots.Count > 0) // can't divide by zero { centerPosition /= _otherBots.Count; } // Figure out what direction to go in local coords Vector3D flockCenterDirection = StraightToTarget_VelocityAware1Worker(centerPosition.ToPoint()); //Vector3D flockCenterDirection = StraightToTargetWorker(centerPosition.ToPoint()); #endregion // Get a cumulative vector that tells how to avoid others Vector3D avoidDirection = AvoidWorker(); // Get the average flock velocity Vector3D commonVelocityDirection = MatchVelocityWorker(); // Go toward the chase point Vector3D chasePointDirection = StraightToTarget_VelocityAware1Worker(_chasePoint); // For now, I will just normalize the two and add them together with equal weight //NOTE: Normalizing gives bad results. The avoid already has a priority magnitude, normalizing wipes it //flockCenterDirection.Normalize(); //avoidDirection.Normalize(); flockCenterDirection /= 2; commonVelocityDirection.Normalize(); chasePointDirection /= (chasePointDirection.Length / 2); Vector3D directionToGo = flockCenterDirection + avoidDirection + commonVelocityDirection + chasePointDirection; // Now that I know where to go, rotate the original thruster direction (0,1,0) to line up with the desired direction Vector3D axis; double radians; Math3D.GetRotation(out axis, out radians, _origThrustDirection, directionToGo); // Thrust Direction _thrustTransform = new RotateTransform3D(new AxisAngleRotation3D(axis, Math1D.RadiansToDegrees(radians))); // Thrust Strength if (_isAttacking) { _thrustPercent = 1d; } else { _thrustPercent = .5d; } }
private RayHitTestParameters GetArrowRay(DraggingModifier whichArrow) { Vector3D origin = new Vector3D(); Vector3D direction = new Vector3D(); Vector3D position = this.Position.ToVector(); Vector3D scale = this.Scale; RotateTransform3D rotateTransform = new RotateTransform3D(new QuaternionRotation3D(this.Orientation)); switch (whichArrow) { case DraggingModifier.ArrowX1: origin = position + rotateTransform.Transform(new Vector3D(GetDistance_Arrow(scale.X), 0, 0)); direction = rotateTransform.Transform(new Vector3D(1, 0, 0)); break; case DraggingModifier.ArrowX2: origin = position - rotateTransform.Transform(new Vector3D(GetDistance_Arrow(scale.X), 0, 0)); direction = rotateTransform.Transform(new Vector3D(-1, 0, 0)); break; case DraggingModifier.ArrowY1: origin = position + rotateTransform.Transform(new Vector3D(0, GetDistance_Arrow(scale.Y), 0)); direction = rotateTransform.Transform(new Vector3D(0, 1, 0)); break; case DraggingModifier.ArrowY2: origin = position - rotateTransform.Transform(new Vector3D(0, GetDistance_Arrow(scale.Y), 0)); direction = rotateTransform.Transform(new Vector3D(0, -1, 0)); break; case DraggingModifier.ArrowZ1: origin = position + rotateTransform.Transform(new Vector3D(0, 0, GetDistance_Arrow(scale.Z))); direction = rotateTransform.Transform(new Vector3D(0, 0, 1)); break; case DraggingModifier.ArrowZ2: origin = position - rotateTransform.Transform(new Vector3D(0, 0, GetDistance_Arrow(scale.Z))); direction = rotateTransform.Transform(new Vector3D(0, 0, -1)); break; default: throw new ApplicationException("Unexpected DraggingModifier: " + whichArrow.ToString()); } // Exit Function return new RayHitTestParameters(origin.ToPoint(), direction); }
private void GetContactPositionaAndNormal() { Vector3D position = new Vector3D(); Vector3D normal = new Vector3D(); //_material1.GetContactPositionAndNormal(ref position, ref normal); Newton.NewtonMaterialGetContactPositionAndNormal(_materialPtr, new NewtonVector3(position).NWVector3, new NewtonVector3(normal).NWVector3); _contactPositionWorld = position.ToPoint(); _contactNormalWorld = normal; }
private Tuple<IsInsideResult, ITriangle, Point3D> DrawZeroTorqueTestSprtIsInside(TriangleIndexed[] hull, Vector3D opposite) { if (Math3D.IsInside_Planes(hull, opposite.ToPoint())) { return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Inside, null, new Point3D()); } Vector3D[] line = new Vector3D[] { opposite * .001d, opposite * .999d }; foreach (ITriangle triangle in hull) { Vector3D dummy1; double dummy2; Vector3D? intersectionPoint; if (Math3D.IsIntersecting_Polygon2D_Line(new Vector3D[] { triangle.Point0.ToVector(), triangle.Point1.ToVector(), triangle.Point2.ToVector() }, line, 3, out dummy1, out dummy2, out intersectionPoint)) { return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Intersects, triangle, intersectionPoint.Value.ToPoint()); } } return new Tuple<IsInsideResult, ITriangle, Point3D>(IsInsideResult.Neither, null, new Point3D()); }
private void DrawZeroTorqueTest2() { //const double MINPERCENT = .005d; // Find 100% thrusters SortedList<int, List<int[]>> fullThrusts = DrawZeroTorqueTest2SprtGetFullThrusts(_vectors); if (fullThrusts.Count == 0) { #region Draw them red if (_showAxiis) { DrawAxiis(new Vector3D(0, 0, 0)); } ScreenSpaceLines3D lines = new ScreenSpaceLines3D(); lines.Thickness = 3d; lines.Color = UtilityWPF.ColorFromHex(LINE_RED); for (int cntr = 0; cntr < _vectors.Length; cntr++) { lines.AddLine(new Point3D(0, 0, 0), _vectors[cntr].ToPoint()); } _visuals.Add(lines); _viewport.Children.Add(lines); #endregion } else { #region Draw all double maxVectorLength = _vectors.Max(o => o.Length); maxVectorLength *= 2.5d; //double offsetX = (fullThrusts.Keys.Count * maxVectorLength) / -2d; double offsetX = 0d; ScreenSpaceLines3D linesFull = new ScreenSpaceLines3D(); linesFull.Thickness = 3d; linesFull.Color = UtilityWPF.ColorFromHex(LINE_GREEN); _visuals.Add(linesFull); _viewport.Children.Add(linesFull); ScreenSpaceLines3D linesCumulative = new ScreenSpaceLines3D(); linesCumulative.Thickness = 3d; linesCumulative.Color = Colors.Chartreuse; _visuals.Add(linesCumulative); _viewport.Children.Add(linesCumulative); ScreenSpaceLines3D linesCumulativeAnti = new ScreenSpaceLines3D(); linesCumulativeAnti.Thickness = 2d; linesCumulativeAnti.Color = UtilityWPF.ColorFromHex(LINE_GREEN_ANTI); _visuals.Add(linesCumulativeAnti); _viewport.Children.Add(linesCumulativeAnti); ScreenSpaceLines3D linesOther = new ScreenSpaceLines3D(); linesOther.Thickness = 3d; linesOther.Color = UtilityWPF.ColorFromHex(LINE_BLUE); _visuals.Add(linesOther); _viewport.Children.Add(linesOther); //NOTE: Only need to grab the key that represents the most number of vectors firing at 100%. The lower keys are trumped //by the higher key int key = fullThrusts.Keys[fullThrusts.Keys.Count - 1]; //foreach (int key in fullThrusts.Keys) //{ double offsetY = (fullThrusts[key].Count * maxVectorLength) / -2d; foreach (int[] fulls in fullThrusts[key]) { Vector3D cumulative = new Vector3D(0, 0, 0); Vector3D offset = new Vector3D(offsetX, offsetY, 0); for (int cntr = 0; cntr < _vectors.Length; cntr++) { if (_showAxiis) { DrawAxiis(offset); } if (fulls.Contains(cntr)) { // Draw the 100%s as green lines (line and anti line) linesFull.AddLine(offset.ToPoint(), (offset + _vectors[cntr]).ToPoint()); cumulative += _vectors[cntr]; //linesFullAnti.AddLine(offset.ToPoint(), (offset - _vectors[cntr]).ToPoint()); } else { // Draw the remaining lines as blue linesOther.AddLine(offset.ToPoint(), (offset + _vectors[cntr]).ToPoint()); } // Draw the hull of the remaining lines TriangleIndexed[] hull = GetHull(_vectors, fulls); if (hull != null) { DrawPossibleHull(hull, offset); } } // Draw the cumulative and anti (it's the anti that was compared to the hull) linesCumulative.AddLine(offset.ToPoint(), (offset + cumulative).ToPoint()); linesCumulativeAnti.AddLine(offset.ToPoint(), (offset - cumulative).ToPoint()); offsetY += maxVectorLength; } // offsetX += maxVectorLength; //} #endregion } }
private ScreenSpaceLines3D[] AddLines(DoubleVector transformedLine, Vector3D rotationAxis) { ScreenSpaceLines3D[] retVal = new ScreenSpaceLines3D[4]; for (int cntr = 0; cntr < retVal.Length; cntr++) { retVal[cntr] = new ScreenSpaceLines3D(true); retVal[cntr].Color = _colors.RotatedLine; if (cntr == 1) { retVal[cntr].Thickness = 3d; // this one isn't really used } else if (cntr == 3) { retVal[cntr].Thickness = 1d; } else { retVal[cntr].Thickness = 6d; } } retVal[0].AddLine(new Point3D(0, 0, 0), transformedLine.Standard.ToPoint()); retVal[1].AddLine(new Point3D(0, 0, 0), new Point3D(0, 0, 0)); // just adding this so everything stays lined up retVal[2].AddLine(new Point3D(0, 0, 0), transformedLine.Orth.ToPoint()); retVal[3].AddLine(new Point3D(0, 0, 0), rotationAxis.ToPoint()); for (int cntr = 0; cntr < retVal.Length; cntr++) { _viewport.Children.Add(retVal[cntr]); } return retVal; }
private void World_Updating(object sender, WorldUpdatingArgs e) { try { #region Remove temp bodies int index = 0; while (index < _tempBodies.Count) { if (_tempBodies[index].ShouldDie()) { foreach (Visual3D visual in _tempBodies[index].PhysicsBody.Visuals) { _viewport.Children.Remove(visual); } _tempBodies[index].PhysicsBody.Dispose(); _tempBodies.RemoveAt(index); } else { index++; } } #endregion if (radFallingSand.IsChecked.Value || (radFallingSandPlates.IsChecked.Value && (DateTime.UtcNow - _lastSandAdd).TotalMilliseconds > 5000d)) { #region Falling Sand bool isPlate = radFallingSandPlates.IsChecked.Value; Color color = UtilityWPF.ColorFromHex("FFF5EE95"); Vector3D size = new Vector3D(.05, .05, .05); double maxDist = 1.1 * size.LengthSquared; double mass = trkMass.Value; double radius = 1d; double startHeight = 1d; TimeSpan lifespan = TimeSpan.FromSeconds(15d); Vector3D velocity = new Vector3D(0, 0, -trkSpeed.Value); int numCubes = isPlate ? 150 : 1; // Calculate positions (they must all be calculated up front, or some sand will be built later) List<Vector3D> positions = new List<Vector3D>(); for (int cntr = 0; cntr < numCubes; cntr++) { Vector3D startPos; while (true) { startPos = Math3D.GetRandomVector_Circular(radius); if (!positions.Any(o => (o - startPos).LengthSquared < maxDist)) { break; } } positions.Add(startPos); } // Place the sand for (int cntr = 0; cntr < numCubes; cntr++) { Vector3D startPos = new Vector3D(positions[cntr].X, positions[cntr].Y, startHeight); Quaternion orientation = isPlate ? Quaternion.Identity : Math3D.GetRandomRotation(); Body body = GetNewBody(CollisionShapeType.Box, color, size, mass, startPos.ToPoint(), orientation, _material_Sand); body.Velocity = velocity; body.LinearDamping = 0d; body.AngularDamping = new Vector3D(0d, 0d, 0d); _tempBodies.Add(new TempBody(body, lifespan)); } // Remember when this was done _lastSandAdd = DateTime.UtcNow; #endregion } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private static ShipPartDNA[] GetRandomThrusters(int count, bool randomOrientations, ThrusterTypeValues thrustType) { const double MINRADIUS = 1.5; const double MAXRADIUS = 3; const double MINSIZE = .5; const double MAXSIZE = 1.5; if (count < 2) { throw new ApplicationException("Must have at least two thrusters"); } List<ShipPartDNA> retVal = new List<ShipPartDNA>(); Random rand = StaticRandom.GetRandomForThread(); double stepAngle = 360d / count; double rangeAngle = 120d / count; // the sum of these pie slices should cover 2/3 of the area Vector3D axis = new Vector3D(0, 0, 1); double startAngle = rand.NextDouble(360); for (int cntr = 0; cntr < count; cntr++) { double angle = startAngle + (cntr * stepAngle); angle += rand.NextDouble(-rangeAngle, rangeAngle); Vector3D position = new Vector3D(rand.NextDouble(MINRADIUS, MAXRADIUS), 0, 0); position = position.GetRotatedVector(axis, angle); double size = rand.NextDouble(MINSIZE, MAXSIZE); //Random direction Quaternion orientation = Quaternion.Identity; if (randomOrientations) { Vector3D standardVect = new Vector3D(0, 0, 1); Vector3D rotatedVect = Math3D.GetRandomVector_Cone(axis, 90); orientation = Math3D.GetRotation(standardVect, rotatedVect); } ThrusterType type; switch (thrustType) { case ThrusterTypeValues.Single: type = ThrusterType.One; break; case ThrusterTypeValues.Dual: type = ThrusterType.Two; break; case ThrusterTypeValues.Six: type = ThrusterType.Two_Two_Two; break; case ThrusterTypeValues.Random: type = UtilityCore.GetRandomEnum<ThrusterType>(ThrusterType.Custom); break; default: throw new ApplicationException("Unknown ThrusterTypeValues: " + thrustType.ToString()); } retVal.Add(new ThrusterDNA() { PartType = Thruster.PARTTYPE, Orientation = orientation, Position = position.ToPoint(), Scale = new Vector3D(size, size, size), ThrusterType = type }); } return retVal.ToArray(); }
private void btnTowerSpikes_Click(object sender, RoutedEventArgs e) { const double BASERADIUS = 2d; try { ClearProjectilesAndExplosions(); ClearBricks(); #region Figure out how many spikes int spikeLimit; if (radFew.IsChecked.Value) { spikeLimit = 15; } else if (radNormal.IsChecked.Value) { spikeLimit = 20; } else if (radMany.IsChecked.Value) { spikeLimit = 25; } else if (radExtreme.IsChecked.Value) { spikeLimit = 30; } else { MessageBox.Show("Unknow number of bricks", this.Title, MessageBoxButton.OK, MessageBoxImage.Error); return; } #endregion List<Vector3D> prevPositions = new List<Vector3D>(); for (int cntr = 0; cntr < spikeLimit; cntr++) { #region Find non colliding position Vector3D pos2D = new Vector3D(); bool havePosition = false; for (int infiniteLoopCntr = 0; infiniteLoopCntr < 100; infiniteLoopCntr++) { // Try this one pos2D = Math3D.GetRandomVector_Circular(20d); havePosition = true; foreach (Vector3D prevPos in prevPositions) { if ((pos2D - prevPos).Length < BASERADIUS * 2) { // Colliding with a previous tower havePosition = false; break; } } if (havePosition) { // This is a unique position, quit trying break; } } if (!havePosition) { // Couldn't find a unique position, quit trying to make towers break; } // Remember the location of this tower prevPositions.Add(pos2D); #endregion BuildSpike(pos2D.ToPoint(), true); } } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private void btnBigSpinner_Click(object sender, RoutedEventArgs e) { try { //Point3D position = Math3D.GetRandomVectorSpherical2D(_rand, 240).ToPoint(); // I want this to act like a sword, so I don't want it starting in the center Vector3D position = new Vector3D(150, 0, 0); position = Math3D.RotateAroundAxis(position, new Vector3D(0, 0, 1), Math1D.GetNearZeroValue(Math.PI * 2d)); position.Z = Math1D.GetNearZeroValue(5d) + 10d; Vector3D velocity = new Vector3D(0, 0, 0); Vector3D angularVelocity = new Vector3D(0, 0, UtilityCore.GetScaledValue_Capped(.1d, 5d, trkBulletSpeed.Minimum, trkBulletSpeed.Maximum, trkBulletSpeed.Value)); //Vector3D dirFacingStand = new Vector3D(1, 0, Math3D.GetNearZeroValue(_rand, .01d)); //Vector3D dirFacingOrth = new Vector3D(0, 0, 1); //dirFacingOrth = dirFacingOrth.GetRotatedVector(new Vector3D(0, -1, 0), Vector3D.AngleBetween(new Vector3D(1, 0, 0), dirFacingStand)); //DoubleVector directionFacing = new DoubleVector(dirFacingStand, dirFacingOrth); DoubleVector directionFacing = _defaultDirectionFacing.GetRotatedVector(new Vector3D(0, 1, 0), Math1D.GetNearZeroValue(1d)); Vector3D size = new Vector3D(350d, 7d, .25d); AddCannonBall(CollisionShapeType.Box, Colors.Silver, size, 3000d, position.ToPoint(), velocity, angularVelocity, directionFacing); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
/// <summary> /// This is a helper method that transforms the position in local coords to the position in world coords /// </summary> public Vector3D PositionToWorld(Vector3D positionLocal) { //NOTE: This transform method acts different based on whether a vector or point is passed in return this.VisualMatrix.Transform(positionLocal.ToPoint()).ToVector(); }
private static bool CanCounterVectors2(Vector3D[] tests, Vector3D[] others) { Vector3D cumulative = new Vector3D(); foreach (Vector3D test in tests) { cumulative += test; } // Make the cumulative point the opposite way (that's what all the tests need) cumulative = cumulative * -1d; // Check for 0D, 1D, 2D, 3D opposition if (others.Length == 0) { #region 0D // Nothing to oppose. The only thing that works is if the test self cancel return Math3D.IsNearZero(cumulative); #endregion } else if (others.Length == 1) { #region 1D // Opposition is a single line // If cumulative's length is longer, then the other is overwhelmed // If the dot product isn't one, then they aren't lined up (cumulative has already been negated) return cumulative.LengthSquared <= others[0].LengthSquared && Math1D.IsNearValue(Vector3D.DotProduct(cumulative.ToUnit(), others[0].ToUnit()), 1d); #endregion } else if (others.Length == 2) { #region 2D // Opposition forms a parallelagram Triangle triangle = new Triangle(new Point3D(0, 0, 0), others[0].ToPoint(), others[1].ToPoint()); if (!Math1D.IsNearZero(Vector3D.DotProduct(triangle.Normal, cumulative))) { return false; } Vector bary = Math3D.ToBarycentric(triangle, cumulative.ToPoint()); return bary.X >= 0d && bary.Y >= 0d && bary.X + bary.Y <= 2d; #endregion } else { #region 3D //NOTE: The reason there is no need to check for 4D, 5D, etc is because cumulative is a 3D vector // Build the hull out of others Point3D[] extremes = GetRemainingExtremes(others, new int[0]); TriangleIndexed[] hull = Math3D.GetConvexHull(extremes); if (hull != null) { return Math3D.IsInside_Planes(hull, cumulative.ToPoint()); } // If hull is null, the points could be coplanar, so try 2D var perimiter = Math2D.GetConvexHull(extremes); if (perimiter != null) { // These are coplanar, see if the cumulative is inside Point? cumulative2D = perimiter.GetTransformedPoint(cumulative.ToPoint()); if (cumulative2D == null) { return false; } else { return perimiter.IsInside(cumulative2D.Value); } } return false; #endregion } }
public Vector3D PositionFromWorld(Vector3D positionWorld) { Matrix3D matrix = this.VisualMatrix; matrix.Invert(); //NOTE: This transform method acts different based on whether a vector or point is passed in return matrix.Transform(positionWorld.ToPoint()).ToVector(); }
private void CreateSpaceStations() { double minDistanceBetweenStations = 200d; List<SpaceStation> stations = new List<SpaceStation>(); #region Home Station // The center has become too violent //// Make one right next to the player at startup (always a distance of 10*sqrt(2), but at a random angle, just so it's not boring) //Vector3D homeLocation = new Vector3D(14.142, 0, 0); //homeLocation = homeLocation.GetRotatedVector(Math3D.GetRandomVectorSpherical(10d), Math3D.GetNearZeroValue(360d)); //CreateSpaceStationsSprtBuild(homeLocation.ToPoint(), stations); #endregion // Make a few more for (int cntr = 0; cntr < 5; cntr++) { // Come up with a position that isn't too close to any other station Vector3D position = new Vector3D(); while (true) { #region Figure out position position = Math3D.GetRandomVector(_boundryMin.ToVector() * .7d, _boundryMax.ToVector() * .7d); // See if this is too close to an existing station bool isTooClose = false; foreach (SpaceStation station in stations) { Vector3D offset = position - station.PositionWorld.ToVector(); if (offset.Length < minDistanceBetweenStations) { isTooClose = true; break; } } if (!isTooClose) { break; } #endregion } CreateSpaceStationsSprtBuild(position.ToPoint(), stations); } }
public static MeshGeometry3D GetCube_IndependentFaces(Vector3D min, Vector3D max) { return GetCube_IndependentFaces(min.ToPoint(), max.ToPoint()); }
private void Brain_TowardCenterOfFlock() { // Calculate the center of position of the flock //TODO: Have a vision limit Vector3D centerPosition = new Vector3D(0, 0, 0); foreach (SwarmBot1 bot in _otherBots) { centerPosition += bot.PhysicsBody.PositionToWorld(bot.PhysicsBody.CenterOfMass).ToVector(); } if (_otherBots.Count > 0) // can't divide by zero { centerPosition /= _otherBots.Count; } // Figure out what direction to go in local coords Vector3D flockCenterDirection = StraightToTarget_VelocityAware1Worker(centerPosition.ToPoint()); // Now that I know where to go, rotate the original thruster direction (0,1,0) to line up with the desired direction Vector3D axis; double radians; Math3D.GetRotation(out axis, out radians, _origThrustDirection, flockCenterDirection); // Thrust Direction _thrustTransform = new RotateTransform3D(new AxisAngleRotation3D(axis, Math1D.RadiansToDegrees(radians))); // Thrust Strength if (_isAttacking) { _thrustPercent = 1d; } else { _thrustPercent = .5d; } }
private void AddRope(Point3D bodyAttachPoint, Point3D anchorPoint, double? radianLimit) { const double SEGMENTLENGTH = .25d; if (_body == null) { throw new InvalidOperationException("The body must be created before this method is called"); } // Figure out how many rope segments to make Vector3D dir = anchorPoint - bodyAttachPoint; int numSegments = Convert.ToInt32(dir.Length / SEGMENTLENGTH); if (numSegments == 0) { numSegments = 1; } double segmentLength = dir.Length / numSegments; DoubleVector dirDbl = new DoubleVector(dir, Math3D.GetArbitraryOrhonganal(dir)); #region Anchor #region WPF Model // Material MaterialGroup materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Anchor))); materials.Children.Add(_colors.AnchorSpecular); // Geometry Mesh MeshGeometry3D mesh = UtilityWPF.GetSphere_LatLon(5, .1d); // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = mesh; // Transform Transform3DGroup transform = new Transform3DGroup(); // rotate needs to be added before translate //rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl); //transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); transform.Children.Add(new TranslateTransform3D(anchorPoint.ToVector())); // Model Visual ModelVisual3D model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Body CollisionHull hull = CollisionHull.CreateNull(_world); Body body = new Body(hull, model.Transform.Value, 0, new Visual3D[] { model }); hull.Dispose(); _anchorBodies.Add(body); // Add to the viewport _viewport.Children.Add(model); #endregion #region Rope for (int cntr = 0; cntr < numSegments; cntr++) { #region WPF Model // Material materials = new MaterialGroup(); materials.Children.Add(new DiffuseMaterial(new SolidColorBrush(_colors.Rope))); materials.Children.Add(_colors.RopeSpecular); // Geometry Mesh mesh = UtilityWPF.GetCylinder_AlongX(7, .03d, segmentLength); CollisionHull ropeHull = CollisionHull.CreateCylinder(_world, 0, .03d, segmentLength, null); // Geometry Model geometry = new GeometryModel3D(); geometry.Material = materials; geometry.BackMaterial = materials; geometry.Geometry = mesh; // Transform transform = new Transform3DGroup(); // rotate needs to be added before translate //Quaternion rotation = _defaultDirectionFacing.GetAngleAroundAxis(dirDbl); Vector3D axisStandard; double radiansStandard; Math3D.GetRotation(out axisStandard, out radiansStandard, _defaultDirectionFacing.Standard, dirDbl.Standard); Quaternion rotationStandard = new Quaternion(axisStandard, Math1D.RadiansToDegrees(radiansStandard)); //Vector3D axisOrth; //double radiansOrth; //Math3D.GetRotation(out axisOrth, out radiansOrth, _defaultDirectionFacing.Orth, dirDbl.Orth); //Quaternion rotationOrth = new Quaternion(axisOrth, Math3D.RadiansToDegrees(radiansOrth)); //Quaternion rotation = rotationStandard.ToUnit() * rotationOrth.ToUnit(); //Quaternion rotation = rotationOrth; Quaternion rotation = rotationStandard; // adding the orth in just messes it up transform.Children.Add(new RotateTransform3D(new QuaternionRotation3D(rotation))); Vector3D segmentPosition = new Vector3D((segmentLength / 2d) + (segmentLength * cntr), 0, 0); segmentPosition = rotation.GetRotatedVector(segmentPosition); segmentPosition += bodyAttachPoint.ToVector(); transform.Children.Add(new TranslateTransform3D(segmentPosition)); // Model Visual model = new ModelVisual3D(); model.Content = geometry; model.Transform = transform; #endregion // Body body = new Body(ropeHull, model.Transform.Value, .1, new Visual3D[] { model }); ropeHull.Dispose(); #region Joint if (cntr == 0) { _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, bodyAttachPoint, _body, body)); } else { Vector3D connectPosition2 = new Vector3D(segmentLength * cntr, 0, 0); connectPosition2 = rotation.GetRotatedVector(connectPosition2); connectPosition2 += bodyAttachPoint.ToVector(); _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition2.ToPoint(), _ropeBodies[_ropeBodies.Count - 1], body)); } if (cntr == numSegments - 1) { Vector3D connectPosition1 = new Vector3D(segmentLength * numSegments, 0, 0); connectPosition1 = rotation.GetRotatedVector(connectPosition1); connectPosition1 += bodyAttachPoint.ToVector(); _ropeJoints.Add(JointBallAndSocket.CreateBallAndSocket(_world, connectPosition1.ToPoint(), body, _anchorBodies[_anchorBodies.Count - 1])); } #endregion _ropeBodies.Add(body); // Add to the viewport _viewport.Children.Add(model); } if (radianLimit != null) { for (int cntr = 0; cntr < _ropeJoints.Count - 1; cntr++) // the connection between the anchor point and rope will never have a limit { ((JointBallAndSocket)_ropeJoints[cntr]).SetConeLimits(dir, radianLimit.Value, null); } } #endregion }
private void CreateSpaceStations() { double xyCoord = _boundryMax.X * .7; double zCoord = _boundryMin.Z - 3; double minDistanceBetweenStations = 200d; #region Home Station // Make one right next to the player at startup (always a distance of 10*sqrt(2), but at a random angle, just so it's not boring) Vector3D homeLocation = new Vector3D(14.142, 0, 0); homeLocation = homeLocation.GetRotatedVector(new Vector3D(0, 0, 1), Math1D.GetNearZeroValue(360d)); CreateSpaceStationsSprtBuild(new Point3D(homeLocation.X, homeLocation.Y, zCoord)); #endregion // Make a few more for (int cntr = 0; cntr < 4; cntr++) { // Come up with a position that isn't too close to any other station Vector3D position = new Vector3D(); while (true) { #region Figure out position position = Math3D.GetRandomVector_Circular(xyCoord); position.Z = zCoord; // See if this is too close to an existing station bool isTooClose = false; foreach (SpaceStation station in _spaceStations) { Vector3D offset = position - station.PositionWorld.ToVector(); if (offset.Length < minDistanceBetweenStations) { isTooClose = true; break; } } if (!isTooClose) { break; } #endregion } CreateSpaceStationsSprtBuild(position.ToPoint()); } }