internal static double RemoveQuantity(double amount, List <Cargo> cargo) { //NOTE: cargo should be sorted from low density to high density, so the lowest quality material is removed first double current = 0d; while (cargo.Count > 0) { double mass = cargo[0].Density * cargo[0].Volume; if (current + mass < amount || Math1D.IsNearValue(current + mass, amount)) { // Eat this whole piece of cargo current += mass; cargo.RemoveAt(0); } else { // Remove some of this cargo double remainingMass = amount - current; double remainingVolume = remainingMass / cargo[0].Density; cargo[0].Volume -= remainingVolume; current = amount; break; } } // Return how much of the request COULDN'T be filled return(amount - current); }
private static ThrusterSolutionMap GetThrusterSolutionMap(ThrusterMap map, ThrustContributionModel model, MassMatrix inertia, double mass) { // Add up the forces Vector3D sumLinearForce = new Vector3D(); Vector3D sumTorque = new Vector3D(); foreach (ThrusterSetting thruster in map.UsedThrusters) { var contribution = model.Contributions.FirstOrDefault(o => o.Item1 == thruster.ThrusterIndex && o.Item2 == thruster.SubIndex); if (contribution == null) { throw new ApplicationException(string.Format("Didn't find contribution for thruster: {0}, {1}", thruster.ThrusterIndex, thruster.SubIndex)); } sumLinearForce += contribution.Item3.TranslationForce * thruster.Percent; sumTorque += contribution.Item3.Torque * thruster.Percent; } // Divide by mass //F=MA, A=F/M double accel = sumLinearForce.Length / mass; Vector3D projected = inertia.Inertia.GetProjectedVector(sumTorque); double angAccel = sumTorque.Length / projected.Length; if (Math1D.IsInvalid(angAccel)) { angAccel = 0; // this happens when there is no net torque } return(new ThrusterSolutionMap(map, accel, angAccel)); }
private static void DrawImage(Image image, double[] values) { double widthHeight = Math.Sqrt(values.Length); // they should be square int widthHeightInt = widthHeight.ToInt_Round(); if (!Math1D.IsNearValue(widthHeight, widthHeightInt)) { throw new ApplicationException("Expected square images"); } BitmapSource source; //if (isColor) //{ // source = UtilityWPF.GetBitmap_RGB(example, width, height); //} //else //{ source = UtilityWPF.GetBitmap(values, widthHeightInt, widthHeightInt); //} image.Source = source; image.Width = source.PixelWidth; // if this isn't set, the image will take up all of the width, and be huge image.Height = source.PixelHeight; }
private static void AddArc(ScreenSpaceLines3D line, Point3D center, double radius, int segments, double startAngle, double stopAngle, bool closeEnd) { startAngle = Math1D.DegreesToRadians(startAngle); stopAngle = Math1D.DegreesToRadians(stopAngle); // swap angles if (startAngle > stopAngle) { double temp = startAngle; startAngle = stopAngle; stopAngle = temp; } Point3D[] points = new Point3D[segments + 1]; double inc = (stopAngle - startAngle) / segments; double r = startAngle; for (int i = 0; i <= segments; i++, r += inc) { points[i] = new Point3D( center.X + (Math.Cos(-r) * radius), center.Y + (Math.Sin(-r) * radius), center.Z); } line.AddPolygon(closeEnd, points); }
private void AddToTab(PartDesignBase part) { var key = new Tuple <PartToolItemBase, PartDesignBase>(part.GetToolItem(), part); _tabParts.Add(key); if (_tabName == null) { _tabName = key.Item1.TabName; } else if (_tabName != key.Item1.TabName) { throw new ArgumentException(string.Format("parts span tabNames, not sure how to handle that: \"{0}\", \"{1}\"", _tabName, key.Item1.TabName)); } int tabIndex = FindOrCreateTab(key); // The standard 2D element is pretty basic, add a tooltip FrameworkElement asFramework = key.Item1.Visual2D as FrameworkElement; if (asFramework != null && asFramework.ToolTip == null) { asFramework.ToolTip = new TextBlock() { Text = string.Format("volume {0}", Math1D.Avg(part.Scale.X, part.Scale.Y, part.Scale.Z).ToStringSignificantDigits(3)), }; } _tabStats[tabIndex].Item2.Children.Add(key.Item1.Visual2D); }
private static Model3D GetAxeSpike(double radius, double length, double scale, double yOffset, MaterialGroup materialMiddle, MaterialGroup materialEdge) { GeometryModel3D retVal = new GeometryModel3D(); retVal.Material = materialEdge; retVal.BackMaterial = materialEdge; double bevel = radius * .2; List <TubeRingBase> tubes = new List <TubeRingBase>(); tubes.Add(new TubeRingRegularPolygon(0, false, radius, radius * 2, true)); tubes.Add(new TubeRingPoint(length, false)); retVal.Geometry = UtilityWPF.GetMultiRingedTube(10, tubes, true, false); Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), -90))); // the tube is built along z, rotate so it's along x if (!Math1D.IsNearZero(yOffset)) { transform.Children.Add(new TranslateTransform3D(0, yOffset, 0)); } transform.Children.Add(new ScaleTransform3D(scale, scale, scale)); retVal.Transform = transform; return(retVal); }
private Vector3D AvoidWorker() { Vector3D retVal = new Vector3D(0, 0, 0); Vector3D myPositionWorld = this.PhysicsBody.PositionToWorld(this.PhysicsBody.CenterOfMass).ToVector(); // center mass should always be at zero, but I want to be consistent foreach (SwarmBot1 bot in _otherBots) { // Get its position relative to me Vector3D botPositionWorld = bot.PhysicsBody.PositionToWorld(bot.PhysicsBody.CenterOfMass).ToVector(); Vector3D offsetLocal = this.PhysicsBody.DirectionFromWorld(botPositionWorld - myPositionWorld); // I need to invert this, because the greater the distance, the less the influence double offsetLength = offsetLocal.Length; if (Math1D.IsNearZero(offsetLength)) { // Can't divide by zero. For now, I'll just skip this bot continue; } double awayForce = 1 / offsetLength; offsetLocal /= offsetLength; // normalize offsetLocal *= -awayForce; // point away from the bot, with the away force strength // Now add this to the return vector retVal += offsetLocal; } // Exit Function return(retVal); }
private static Matrix3D GetProjectionMatrix(PerspectiveCamera camera, double aspectRatio) { if (camera == null) { throw new ArgumentNullException("camera"); } // This math is identical to what you find documented for // D3DXMatrixPerspectiveFovRH with the exception that in // WPF the camera's horizontal rather the vertical // field-of-view is specified. double hFoV = Math1D.DegreesToRadians(camera.FieldOfView); double zn = camera.NearPlaneDistance; double zf = camera.FarPlaneDistance; double xScale = 1 / Math.Tan(hFoV / 2); double yScale = aspectRatio * xScale; double m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf)); double m43 = zn * m33; return(new Matrix3D( xScale, 0, 0, 0, 0, yScale, 0, 0, 0, 0, m33, -1, 0, 0, m43, 0)); }
private static Model3D GetAxeCylinder(double radius, double height, double scale, double yOffset, MaterialGroup material) { GeometryModel3D retVal = new GeometryModel3D(); retVal.Material = material; retVal.BackMaterial = material; double bevel = radius * .2; List <TubeRingBase> tubes = new List <TubeRingBase>(); tubes.Add(new TubeRingRegularPolygon(0, false, radius - bevel, radius - bevel, true)); tubes.Add(new TubeRingRegularPolygon(bevel, false, radius, radius, false)); tubes.Add(new TubeRingRegularPolygon(height - (bevel * 2), false, radius, radius, false)); tubes.Add(new TubeRingRegularPolygon(bevel, false, radius - bevel, radius - bevel, true)); retVal.Geometry = UtilityWPF.GetMultiRingedTube(10, tubes, true, true); Transform3DGroup transform = new Transform3DGroup(); transform.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), 90))); // the tube is built along z, rotate so it's along y if (!Math1D.IsNearZero(yOffset)) { transform.Children.Add(new TranslateTransform3D(0, yOffset, 0)); } transform.Children.Add(new ScaleTransform3D(scale, scale, scale)); retVal.Transform = transform; return(retVal); }
private Tuple <Point3D, Vector3D> GetPositionVelocity(double mass) { //mass of ice = .46 //mass of platinum = 10.7 //small asteroid = 80-226 //large asteroid = 550-916 // Percent (more massive toward the center) double percent = UtilityCore.GetScaledValue_Capped(.05, .85, 0, 1000, mass); percent = 1d - percent; //GetScaledValue can't handle inverted ranges, so invert outside of it percent = percent * percent * percent; // it works better with nonlinear // Position Vector3D posXY = Math3D.GetRandomVector_Circular(_boundryMax.X * (percent - .03), _boundryMax.X * (percent + .03)); double z = Math1D.GetNearZeroValue(_boundryMax.Z) * .15; Point3D position = new Point3D(posXY.X, posXY.Y, z); // Velocity double speed = UtilityCore.GetScaledValue_Capped(_boundryMax.X * .001, _boundryMax.X * .05, 0, 1, percent); Vector3D velocity = posXY.ToUnit().GetRotatedVector(new Vector3D(0, 0, 1), -90) * speed; return(Tuple.Create(position, velocity)); }
public Evaluator_WeaponSpin(WorldAccessor worldAccessor, TrainingRoom room, BotTrackingStorage log, ExperimentInitArgs_Activation activation, double weaponSpeed_Min, double weaponSpeed_Max, HyperNEAT_Args hyperneatArgs = null, double maxEvalTime = 15) { _worldAccessor = worldAccessor; _room = room; _log = log; _activation = activation; _hyperneatArgs = hyperneatArgs; _maxEvalTime = maxEvalTime; // Set distances based on room size (or take as params?, or just a percent param?) double roomWidth = Math1D.Min ( room.AABB.Item2.X - room.AABB.Item1.X, room.AABB.Item2.Y - room.AABB.Item1.Y, room.AABB.Item2.Z - room.AABB.Item1.Z ); // Want radius, not diameter _roomRadius = roomWidth / 2; _maxDistance2 = _roomRadius * MULT_MAXDIST2; _maxDistance = _roomRadius * MULT_MAXDIST; // Weapon Speed _weaponSpeed_Min = weaponSpeed_Min; _weaponSpeed_Max = weaponSpeed_Max; _weaponSpeed_Max2 = _weaponSpeed_Max + ((_weaponSpeed_Max - _weaponSpeed_Min) / 2); }
private void PhysicsBody_ApplyForceAndTorque(object sender, BodyApplyForceAndTorqueArgs e) { // See if there is anything to do if (_desiredOrientation == null) { return; } //TODO: Implement this.Offset //TODO: Allow rotations in the destination axis Vector3D current = e.Body.DirectionToWorld(new Vector3D(0, 0, 1)); Quaternion rotation = Math3D.GetRotation(current, _desiredOrientation.Value); if (rotation.IsIdentity) { // Don't set anything. If they are rotating along the allowed axis, then no problem. If they try // to rotate off that axis, another iteration of this method will rotate back //e.Body.AngularVelocity = new Vector3D(0, 0, 0); return; } // According to the newton wiki, angular velociy is radians per second Vector3D newAngVel = rotation.Axis.ToUnit() * Math1D.DegreesToRadians(rotation.Angle); newAngVel *= _multiplier; if (this.MaxVelocity != null && newAngVel.LengthSquared > this.MaxVelocity.Value * this.MaxVelocity.Value) { newAngVel = newAngVel.ToUnit() * this.MaxVelocity.Value; } e.Body.AngularVelocity = newAngVel; }
private void RandomCamera_Click(object sender, RoutedEventArgs e) { try { // Position Vector3D position = Math3D.GetRandomVector_Spherical(CAMERADISTANCE / 2, CAMERADISTANCE * 2); // Look Direction Vector3D lookDirection = position * -1; Vector3D rotateAxis = Math3D.GetRandomVector_Cone(Math3D.GetArbitraryOrhonganal(lookDirection), 0, 20, 1, 1); Quaternion rotate = new Quaternion(rotateAxis, Math1D.GetNearZeroValue(20)); lookDirection = rotate.GetRotatedVector(lookDirection); // Up Vector Vector3D up = Math3D.GetArbitraryOrhonganal(lookDirection); // Commit _camera.Position = position.ToPoint(); _camera.LookDirection = lookDirection; _camera.UpDirection = up; } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
private bool AreForcesZero() { if (this.Field == null || _triangles == null || _triangles.Length == 0) { return(true); } bool isZeroForce = false; if (this.Field is FluidFieldUniform) { var velocities = this.Field.GetForce(new[] { new Point3D(0, 0, 0) }, 1); isZeroForce = Math1D.IsNearZero(velocities[0].Item1.LengthSquared); } if (isZeroForce && (this.Body == null || (Math1D.IsNearZero(this.Body.Velocity.LengthSquared) && Math1D.IsNearZero(this.Body.AngularVelocity.LengthSquared)))) { return(true); } else { return(false); } }
public void Update_AnyThread(double elapsedTime) { Vector3D velocity = this.Bot.VelocityWorld.ToUnit(); double dot = Vector3D.DotProduct((Vector3D)_velocityUnitLastTick, velocity); _velocityUnitLastTick = velocity; double score; if (Math1D.IsInvalid(dot)) { score = .5d; // not sure what to do here } else if (dot < _minDot) { //score = UtilityHelper.GetScaledValue(0, 1, -1, _minDot, dot); score = 0d; // this class is pretty high scoring as it is, so I don't really want a gradient } else { score = 1d; // I don't want a gradient above this min. Circular motion will have a dot of zero, and shouldn't be favored or punished over straight line motion } _score = (double)_score + (score * elapsedTime); }
/// <summary> /// The hopfield can only store booleans. So low and high tell how to map from external to local values /// </summary> /// <param name="midValue"> /// If left null, this will just be the value between low and high. /// But if you want to exaggerate lows, make this larger than that average (because all values less than this go low). Or the /// other way to exaggerate highs. /// </param> public Hopfield(int nodeCount, double lowValue, double highValue, double?midValue = null) { _nodeCount = nodeCount; _lowValue = lowValue; _highValue = highValue; _midValue = midValue ?? Math1D.Avg(lowValue, highValue); }
/// <summary> /// a1 is line1 start, a2 is line1 end, b1 is line2 start, b2 is line2 end /// </summary> /// <remarks> /// Got this here: /// http://stackoverflow.com/questions/14480124/how-do-i-detect-triangle-and-rectangle-intersection /// /// A similar article: /// http://www.flipcode.com/archives/Point-Plane_Collision.shtml /// </remarks> private static Vector?Intersects(Vector a1, Vector a2, Vector b1, Vector b2) { Vector b = Vector.Subtract(a2, a1); Vector d = Vector.Subtract(b2, b1); double bDotDPerp = (b.X * d.Y) - (b.Y * d.X); // if b dot d == 0, it means the lines are parallel so have infinite intersection points if (Math1D.IsNearZero(bDotDPerp)) { return(null); } Vector c = Vector.Subtract(b1, a1); double t = (c.X * d.Y - c.Y * d.X) / bDotDPerp; if (t < 0 || t > 1) { return(null); } double u = (c.X * b.Y - c.Y * b.X) / bDotDPerp; if (u < 0 || u > 1) { return(null); } // Return the intersection point return(Vector.Add(a1, Vector.Multiply(b, t))); }
/// <summary> /// Figures out how much of the force should go to each point. The distances are distances from the point of impact. /// NOTE: This is basically: (1+baseConst)^-x /// </summary> /// <param name="baseConst"> /// Any number from 0 to infinity. Realistic values should be between .5 and 8. There's nothing magical about using e as /// the constant, it just seems to have a good amount of curve /// </param> /// <remarks> /// This doesn't need to create super realistic percents. If in doubt, use a larger base constant, which will give more of the force /// to the closer points. The physics engine won't let close objects fly past farther, so just like racking pool balls, the outer will /// fly out. But distributing the force a bit should help with jumpy behavior if the physics engine is under load /// /// I don't know for sure, but I'm guessing the shape of the curve should be roughly 1/x^2. This method isn't that, but should /// be similar enough. /// </remarks> private static double[] GetPercentOfProjForce(double[] distances, double baseConst = Math.E) { var avg_stdev = Math1D.Get_Average_StandardDeviation(distances); double scale = avg_stdev.Item2 / avg_stdev.Item1; scale *= baseConst; scale += 1; var deviations = distances. Select(o => { double distFromAvg = Math.Abs(o - avg_stdev.Item1); double deviationsFromAvg = distFromAvg / avg_stdev.Item2; if (o > avg_stdev.Item1) { deviationsFromAvg = -deviationsFromAvg; } //return Math.Pow(Math.E, deviationsFromAvg); return(Math.Pow(scale, deviationsFromAvg)); }). ToArray(); double sum = deviations.Sum(); return(deviations. Select(o => o / sum). ToArray()); }
/// <summary> /// This keeps the cargo hold sorted by density /// NOTE: If volumes change outside of this thread, then this could place cargo in an imperfect order. No real damage, just be aware /// </summary> internal static void Add(List <Cargo> cargoHold, Cargo cargo) { if (cargoHold.Count == 0) { cargoHold.Add(cargo); return; } for (int cntr = 0; cntr < cargoHold.Count; cntr++) { if (cargo.Density < cargoHold[cntr].Density) { // This is less dense, put it here cargoHold.Insert(cntr, cargo); return; } else if (Math1D.IsNearValue(cargo.Density, cargoHold[cntr].Density) && cargo.Volume < cargoHold[cntr].Volume) { // This is the same density, but has less volume, so put it here cargoHold.Insert(cntr, cargo); return; } } // This is more desnse than everything else, put it at the end cargoHold.Add(cargo); }
private void TransitionToFinal() { List <TrackingCandidate> finalists = new List <TrackingCandidate>(); #region Find finished finalists // Get all the finalists that are finished int index = 0; while (index < _finalists.Count) { TrackingCandidate finalist = _finalists[index]; int numStarted = finalist.NumStarted; if (numStarted >= this.FinalistCount && numStarted == finalist.NumFinished) { if (!Math1D.IsNearZero(finalist.GetAverage())) // don't let zero scores into the final (the way to get a zero score is to become a candidate, but then each attempt resulted in a zero score) { finalists.Add(finalist); } _finalists.RemoveAt(index); } else { index++; } } #endregion if (finalists.Count > 0) { this.Final.StoreWinners(finalists.Select(o => new WinnerList.WinningBean(o.DNA, o.GetAverage(), 0d)).ToArray()); } }
public DamageProps CalculateDamage(MaterialCollision[] collisions) { if (!_isFullySetUp || collisions.Length == 0) { return(null); } double damangeMult = GetDamageMultiplier(); if (Math1D.IsNearZero(damangeMult)) { return(null); } var avgCollision = MaterialCollision.GetAverageCollision(collisions, _bot.PhysicsBody); //TODO: See if this position is along the ramming direction double speed = avgCollision.Item2 / 10; // a speed of 10 is considered an average impact speed double damage = speed * damangeMult; DamageProps retVal = new DamageProps(avgCollision.Item1, damage); // The act of hitting something needs to stop the ram, otherwise, they just keep pushing against the item // and continue to do damage StopRamming(); return(retVal); }
private void Update_Position_Orbit(double elapsedTime) { //NOTE: This method doesn't try to limit motion inside the boundry rectangle, it just used the boundry to calculate orbit radius double orbitRadius = this.Boundry.Length * .8; Vector3D posVect = this.Position.ToVector(); // Fix position if (Math3D.IsNearZero(posVect)) { posVect = Math3D.GetRandomVector_Spherical_Shell(orbitRadius); } else if (!Math1D.IsNearValue(this.Position.ToVector().LengthSquared, orbitRadius * orbitRadius)) { posVect = posVect.ToUnit() * orbitRadius; } // Figure out how many degrees to turn double circ = Math.PI * orbitRadius * 2; double angle = this.Speed_Position / circ * 360 * elapsedTime; posVect = posVect.GetRotatedVector(_velocityUnit, angle); // using the velocity vector as the axis of rotation this.Position = posVect.ToPoint(); }
private void AddEgg_Click(object sender, RoutedEventArgs e) { try { if (_bots.Count == 0) { MessageBox.Show("Add a bot first", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } Swimbot bot = _bots[StaticRandom.Next(_bots.Count)]; Point3D position = bot.PositionWorld + Math3D.GetRandomVector_Spherical_Shell(bot.Radius * 1.5d); // The radius should be 20% the size of the adult ship ShipDNA dna = bot.GetNewDNA(); double radius = dna.PartsByLayer.SelectMany(o => o.Value). Max(o => o.Position.ToVector().Length + Math1D.Max(o.Scale.X, o.Scale.Y, o.Scale.Z)) * .2d; Egg <ShipDNA> egg = new Egg <ShipDNA>(position, radius, _world, _material_Egg, _itemOptions, dna); egg.PhysicsBody.AngularVelocity = bot.PhysicsBody.AngularVelocity; egg.PhysicsBody.Velocity = bot.PhysicsBody.Velocity; egg.PhysicsBody.ApplyForceAndTorque += new EventHandler <BodyApplyForceAndTorqueArgs>(Egg_ApplyForceAndTorque); _map.AddItem(egg); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
public Evaluator3(WorldAccessor worldAccessor, TrainingRoom room, BotTrackingStorage log, ExperimentInitArgs_Activation activation, HyperNEAT_Args hyperneatArgs = null, double maxEvalTime = 15, double?initialRandomVelocity = null) { _worldAccessor = worldAccessor; _room = room; _log = log; _activation = activation; _hyperneatArgs = hyperneatArgs; _maxEvalTime = maxEvalTime; _initialRandomVelocity = initialRandomVelocity; // Set distances based on room size (or take as params?, or just a percent param?) double roomWidth = Math1D.Min ( room.AABB.Item2.X - room.AABB.Item1.X, room.AABB.Item2.Y - room.AABB.Item1.Y, room.AABB.Item2.Z - room.AABB.Item1.Z ); // Want radius, not diameter _roomRadius = roomWidth / 2; _maxDistance2 = _roomRadius * MULT_MAXDIST2; _maxDistance = _roomRadius * MULT_MAXDIST; _minDistance = _roomRadius * MULT_MINDIST; }
private void btnGarbage2_Click(object sender, RoutedEventArgs e) { try { if (_prevSketches.Count == 0) { MessageBox.Show("Need stored images first", this.Title, MessageBoxButton.OK, MessageBoxImage.Warning); return; } // Pick a random sketch var sketch = StaticRandom.NextItem(_prevSketches); Color[] colors = sketch.BitmapColors.GetColors(0, 0, sketch.Bitmap.PixelWidth, sketch.Bitmap.PixelHeight); Color[] inverseColors = colors. Select(o => { bool isBlack = (o.A > 200 && Math1D.Avg(o.R, o.G, o.B) < 20); // Invert the color return(isBlack ? Colors.Transparent : Colors.Black); }). ToArray(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), this.Title, MessageBoxButton.OK, MessageBoxImage.Error); } }
public double AddQuantity(IContainer pullFrom, double amount, bool exactAmountOnly) { lock (_lock) { double actualAmount = amount; // See if I can handle that much double max = _quantityMax_Usable ?? _quantityMax; if (_quantityCurrent + actualAmount > max) { actualAmount = max - _quantityCurrent; } if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount)) { actualAmount = 0d; } if (actualAmount != 0d) { // Now try to pull that much out of the source container actualAmount -= pullFrom.RemoveQuantity(actualAmount, exactAmountOnly); // Add the value _quantityCurrent += actualAmount; } // Exit function return(amount - actualAmount); } }
public double AddQuantity(double amount, bool exactAmountOnly) { lock (_lock) { double actualAmount = amount; // Figure out what should actually be stored double max = _quantityMax_Usable ?? _quantityMax; if (_quantityCurrent + actualAmount > max) { actualAmount = max - _quantityCurrent; } //if (exactAmountOnly && actualAmount != amount) if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount)) { actualAmount = 0d; } // Add the value _quantityCurrent += actualAmount; // Exit function return(amount - actualAmount); } }
private double AddQuantity_priv(double amount, bool exactAmountOnly) { double current = GetQuantityCurrent(); double max = GetQuantityMax().Item1; // using the destroyed aware max double actualAmount = amount; // Figure out what should actually be stored if (current + actualAmount > max) { actualAmount = max - current; } if (exactAmountOnly && !Math1D.IsNearValue(actualAmount, amount)) { actualAmount = 0d; } if (actualAmount != 0d) { #region Add it // Ensure that the containers are equalized switch (_ownership) { case ContainerOwnershipType.GroupIsSoleOwner: // Nothing to do break; case ContainerOwnershipType.QuantitiesCanChange: EqualizeContainers(false); break; case ContainerOwnershipType.QuantitiesMaxesCanChange: EqualizeContainers(true); break; default: throw new ApplicationException("Unknown ContainerOwnershipType: " + _ownership.ToString()); } // Add the value evenly for (int cntr = 0; cntr < _containers.Count; cntr++) { if (!_destroyed[cntr]) { _containers[cntr].Item1.QuantityCurrent += actualAmount * _ratios[cntr].Item1; // using the destroyed aware ratio } } // Cache the new value (this is used if sole owner) _current = current + actualAmount; #endregion } // Exit function return(amount - actualAmount); }
public static decimal GetCredits_ShipPart(ShipPartDNA dna) { decimal baseAmt = GetCredits_ShipPart_Base(dna.PartType ?? ""); decimal scale = Convert.ToDecimal(Math1D.Avg(dna.Scale.X, dna.Scale.Y, dna.Scale.Z)); return(baseAmt * scale); }
private void PhysicsBody_BodyMoved(object sender, EventArgs e) { if (!_isVisualAdded) { return; } // Graphics need to be updated here. If I wait until world update, this graphic will be one frame // behind, which is very noticable when the bot has a high velocity double damageMult = GetDamageMultiplier(); Vector3D velocity = _bot.VelocityWorld; var dna = this.DNA; // Light size double lightSize = UtilityCore.GetScaledValue_Capped(0, _bot.Radius * 4, 0, dna.DamageMult * 20, damageMult); UtilityWPF.SetAttenuation(_light, lightSize, .1d); _light.Color = Color.FromArgb(Convert.ToByte(UtilityCore.GetScaledValue_Capped(0, 192, 0, dna.DamageMult * 10, damageMult)), 255, 0, 0); // Scale double scale; if (damageMult < dna.DamageMult * 4) { scale = 0; } else { scale = UtilityCore.GetScaledValue_Capped(0, _bot.Radius, dna.DamageMult * 4, dna.DamageMult * 25, damageMult); } _scale.ScaleX = scale; _scale.ScaleY = scale; _scale.ScaleZ = scale; // Translate Point3D position = _bot.PositionWorld + (velocity.ToUnit() * (_bot.Radius * UtilityCore.GetScaledValue_Capped(1.05, 1.3, 0, dna.DamageMult * 25, damageMult))); _translate.OffsetX = position.X; _translate.OffsetY = position.Y; _translate.OffsetZ = position.Z; // Rotate Vector3D xAxis = new Vector3D(1, 0, 0); Vector3D axis = Vector3D.CrossProduct(xAxis, velocity); double angle = Vector3D.AngleBetween(xAxis, velocity); if (Math3D.IsNearZero(axis) || Math1D.IsNearZero(angle)) { _rotate.Quaternion = Quaternion.Identity; } else { _rotate.Quaternion = new Quaternion(axis, angle); } }