/// <summary> /// Turns the selected Rotation toward a given point using the provided interpolation settings /// </summary> /// <param name="position">end desired position to LookAt</param> /// <param name="rotationType">Rotation (Yaw/Pitch/Roll) which will turn</param> /// <param name="interpolateType">Rotation interpolation (Lerp/Slerp/RotateTowards/etc.) type used</param> /// <param name="interpolateRate">Rate of the interpolation (desired ranges based on selected interpolation type)</param> /// <param name="up">Up direction to maintain (null will try to maintain the transform's current up direction)</param> public void TurnToward(Vector3 position, Rotation rotationType, MathExtensions.QuaternionInterpolationType interpolateType, float interpolateRate, Vector3? up = null) { Transform trans = GetTransform(rotationType); Quaternion desiredFacing = GetFacingDirectionOnPlane(rotationType, position, up); trans.rotation = MathExtensions.Interpolate(interpolateType, trans.rotation, desiredFacing, interpolateRate); }
/// <summary> /// Calculates this mathematical expression (using gradian). /// </summary> /// <param name="parameters">An object that contains all parameters and functions for expressions.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteGradian(ExpressionParameters parameters) { var radian = (double)m_argument.Execute(parameters) * Math.PI / 200; return(MathExtensions.Csc(radian)); }
/// <summary> /// Calculates this mathematical expression (using degree). /// </summary> /// <param name="degree">The calculation result of argument.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteDergee(double degree) { return(MathExtensions.Acot(degree) / Math.PI * 180); }
/// <summary> /// Gets all possible actions for the active character and splits them into offensive and defensive actions, /// giving each a priority based on the amount of healing, damage, and/or ai weight provided by the action. /// </summary> /// <returns>A struct providing the action priorities of offensive and defensive actions.</returns> protected virtual ActionPriorities EvaluateActions() { var defensiveActionsPoints = new Dictionary <ActionBase, int>(); var offensiveActionsPoints = new Dictionary <ActionBase, int>(); var defensiveActionPriorities = new Dictionary <ActionBase, int>(); var offensiveActionPriorities = new Dictionary <ActionBase, int>(); var allActions = new List <ActionBase>(); allActions.AddRange(_activeCharacter.Attacks); allActions.AddRange(_activeCharacter.SpellList); allActions.AddRange(_activeCharacter.SkillList); var consumables = _activeCharacter.Inventory .Where(item => item is Consumable) .Select(item => ((Consumable)item).ItemSpell); allActions.AddRange(consumables); // Use average max health as basis for effectiveness of damage and healing int averageMaxHealth = 0; foreach (var character in AICharacters) { averageMaxHealth += character.CurrentMaxHealth; } averageMaxHealth /= AICharacters.Count(); // Calculate total healing and damage and use it to determine if an action is offensive or defensive foreach (var action in allActions) { int damage = DamageCalculator.GetDamageAsInt(_activeCharacter, action); int healing = DamageCalculator.GetHealing(_activeCharacter, action); int percentHealing = DamageCalculator.GetHealingPercentage(_activeCharacter, action); int netDamage = damage - healing; if (netDamage < 0 || percentHealing > 0 || !action.IsOffensive) { int maxPotential = -netDamage; maxPotential += (percentHealing * averageMaxHealth / 100); defensiveActionsPoints[action] = maxPotential; } else { int maxPotential = netDamage; offensiveActionsPoints[action] = maxPotential; } } int medianHealing = MathExtensions.GetMedian(defensiveActionsPoints.Values.ToList()); int medianDamage = MathExtensions.GetMedian(offensiveActionsPoints.Values.ToList()); // Assign action priorities based on how an action performs on par with other actions foreach (var key in defensiveActionsPoints.Keys) { int healing = defensiveActionsPoints[key]; defensiveActionPriorities[key] = key.AiWeight; if (medianHealing > 0) { if (PercentageCalculator.GetPercentage(healing, medianHealing) >= 150) { defensiveActionPriorities[key] += 3; } else if (PercentageCalculator.GetPercentage(healing, medianHealing) >= 120) { defensiveActionPriorities[key] += 2; } } else { defensiveActionPriorities[key] += 1; } } foreach (var key in offensiveActionsPoints.Keys) { int damage = offensiveActionsPoints[key]; offensiveActionPriorities[key] = key.AiWeight; if (medianDamage > 0) { if (PercentageCalculator.GetPercentage(damage, medianDamage) >= 150) { offensiveActionPriorities[key] += 3; } else if (PercentageCalculator.GetPercentage(damage, medianDamage) >= 120) { offensiveActionPriorities[key] += 2; } } else { offensiveActionPriorities[key] += 1; } } return(new ActionPriorities() { DefensiveActionPriorities = defensiveActionPriorities, OffensiveActionPriorities = offensiveActionPriorities }); }
public void ExecuteGradianTest() { var exp = new Csc(new Number(1)); Assert.Equal(MathExtensions.Csc(Math.PI / 200), exp.Execute(AngleMeasurement.Gradian)); }
/// <summary> /// Calculates this mathematical expression (using degree). /// </summary> /// <param name="degree">The calculation result of argument.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteDergee(double degree) { return(MathExtensions.Cot(degree * Math.PI / 180)); }
private static bool SurfaceRotateTool(SelectionType selectionType, Rect dragArea) { var id = GUIUtility.GetControlID(kSurfaceRotateHash, FocusType.Keyboard, dragArea); if (!ChiselUVToolCommon.SurfaceToolBase(id, selectionType, dragArea)) { return(false); } bool needRepaint = false; if (!ChiselUVToolCommon.IsToolEnabled(id)) { needRepaint = haveRotateStartAngle; haveRotateStartAngle = false; ChiselUVToolCommon.pointHasSnapped = false; } switch (Event.current.GetTypeForControl(id)) { // TODO: support rotating texture using keyboard? case EventType.Repaint: { if (haveRotateStartAngle) { var toWorldVector = ChiselUVToolCommon.worldDragDeltaVector; var magnitude = toWorldVector.magnitude; toWorldVector /= magnitude; // TODO: need a nicer visualization here, show delta rotation, angles etc. Handles.DrawWireDisc(ChiselUVToolCommon.worldStartPosition, ChiselUVToolCommon.worldProjectionPlane.normal, magnitude); if (haveRotateStartAngle) { var snappedToWorldVector = Quaternion.AngleAxis(rotateAngle, ChiselUVToolCommon.worldDragPlane.normal) * fromWorldVector; Handles.DrawDottedLine(ChiselUVToolCommon.worldStartPosition, ChiselUVToolCommon.worldStartPosition + (fromWorldVector * magnitude), 4.0f); Handles.DrawDottedLine(ChiselUVToolCommon.worldStartPosition, ChiselUVToolCommon.worldStartPosition + (snappedToWorldVector * magnitude), 4.0f); } else { Handles.DrawDottedLine(ChiselUVToolCommon.worldStartPosition, ChiselUVToolCommon.worldStartPosition + (toWorldVector * magnitude), 4.0f); } } if (ChiselUVToolCommon.IsToolEnabled(id)) { if (haveRotateStartAngle && ChiselUVToolCommon.pointHasSnapped) { ChiselUVToolCommon.RenderIntersectionPoint(); ChiselUVToolCommon.RenderSnapEvent(); } } break; } case EventType.MouseDrag: { if (!ChiselUVToolCommon.IsToolEnabled(id)) { break; } if (ChiselUVToolCommon.StartToolDragging()) { haveRotateStartAngle = false; ChiselUVToolCommon.pointHasSnapped = false; } var toWorldVector = ChiselUVToolCommon.worldDragDeltaVector; if (!haveRotateStartAngle) { var handleSize = HandleUtility.GetHandleSize(ChiselUVToolCommon.worldStartPosition); var minDiameterSqr = handleSize * kMinRotateDiameter; // Only start rotating when we've moved the cursor far away enough from the center of rotation if (toWorldVector.sqrMagnitude > minDiameterSqr) { // Switch to rotation mode, we have a center and a start angle to compare with, // from now on, when we move the mouse we change the rotation angle relative to this first angle. haveRotateStartAngle = true; ChiselUVToolCommon.pointHasSnapped = false; fromWorldVector = toWorldVector.normalized; rotateAngle = 0; // We override the snapping settings to only allow snapping against vertices & edges, // we do this only after we have our starting vector, so that when we rotate we're not constantly // snapping against the grid when we really just want to be able to snap against the current rotation step. // On the other hand, we do want to be able to snap against vertices .. ChiselUVToolCommon.toolSnapOverrides = SnapSettings.UVGeometryVertices | SnapSettings.UVGeometryEdges; } } else { // Get the angle between 'from' and 'to' on the plane we're dragging over rotateAngle = MathExtensions.SignedAngle(fromWorldVector, toWorldVector.normalized, ChiselUVToolCommon.worldDragPlane.normal); // If we snapped against something, ignore angle snapping if (!ChiselUVToolCommon.pointHasSnapped) { rotateAngle = ChiselUVToolCommon.SnapAngle(rotateAngle); } RotateSurfacesInWorldSpace(ChiselUVToolCommon.worldStartPosition, ChiselUVToolCommon.worldDragPlane.normal, -rotateAngle); // TODO: figure out why this is reversed } break; } } return(needRepaint); }
private static int stbi__zbuild_huffman(stbi__zhuffman z, FakePtr <byte> sizelist, int num) { var i = 0; var k = 0; var code = 0; var next_code = new int[16]; var sizes = new int[17]; sizes.Clear(); z.fast.Clear(); for (i = 0; i < num; ++i) { ++sizes[sizelist[i]]; } sizes[0] = 0; for (i = 1; i < 16; ++i) { if (sizes[i] > 1 << i) { Decoder.stbi__err("bad sizes"); } } code = 0; for (i = 1; i < 16; ++i) { next_code[i] = code; z.firstcode[i] = (ushort)code; z.firstsymbol[i] = (ushort)k; code = code + sizes[i]; if (sizes[i] != 0) { if (code - 1 >= 1 << i) { Decoder.stbi__err("bad codelengths"); } } z.maxcode[i] = code << (16 - i); code <<= 1; k += sizes[i]; } z.maxcode[16] = 0x10000; for (i = 0; i < num; ++i) { var s = (int)sizelist[i]; if (s != 0) { var c = next_code[s] - z.firstcode[s] + z.firstsymbol[s]; var fastv = (ushort)((s << 9) | i); z.size[c] = (byte)s; z.value[c] = (ushort)i; if (s <= 9) { var j = MathExtensions.stbi__bit_reverse(next_code[s], s); while (j < 1 << 9) { z.fast[j] = fastv; j += 1 << s; } } ++next_code[s]; } } return(1); }
private void RecursiveBuild(IntermediateOCTreeNode node, OCTPoly[] PolyList, Vector3 center, Vector3 extents, int depth) { var planeArray = new[] { MathExtensions.PlaneFromPointNormal(center + (planeOffsets[0] * extents), planeNormals[0]), MathExtensions.PlaneFromPointNormal(center + (planeOffsets[1] * extents), planeNormals[1]), MathExtensions.PlaneFromPointNormal(center + (planeOffsets[2] * extents), planeNormals[2]), MathExtensions.PlaneFromPointNormal(center + (planeOffsets[3] * extents), planeNormals[3]), MathExtensions.PlaneFromPointNormal(center + (planeOffsets[4] * extents), planeNormals[4]), MathExtensions.PlaneFromPointNormal(center + (planeOffsets[5] * extents), planeNormals[5]) }; var polyArray = new OCTPoly[PolyList.Length]; var index = 0; while (index < PolyList.Length) { polyArray[index] = new OCTPoly(PolyList[index]); index++; } for (var i = 0; i < planeArray.Length; i++) { var list = new List <OCTPoly>(); for (var j = 0; j < polyArray.Length; j++) { int num4; var newPolys = new OCTPoly[2]; Split(polyArray[j], planeArray[i], ref newPolys, out num4); index = 0; while (index < num4) { var plane = new Plane(newPolys[index].Verts[0], newPolys[index].Verts[1], newPolys[index].Verts[2]); if (!float.IsNaN(plane.Normal.X)) { list.Add(newPolys[index]); } index++; } } polyArray = new OCTPoly[list.Count]; index = 0; while (index < list.Count) { polyArray[index] = new OCTPoly(list[index]); index++; } } if ((polyArray.Length <= MaxPolygonsPerNode) || (depth >= MaxSubdivisions)) { node.Polys = new OCTPoly[polyArray.Length]; if (polyArray.Length > 0) { for (index = 0; index < polyArray.Length; index++) { node.Polys[index] = new OCTPoly(polyArray[index]); } } } else { node.Children = new IntermediateOCTreeNode[8]; for (index = 0; index < 8; index++) { node.Children[index] = new IntermediateOCTreeNode(); var vector = (extents * 0.5f); var vector2 = center + (nodeOffsets[index] * vector); node.Children[index].Bounds = new BoundingBox(vector2 - vector, vector2 + vector); RecursiveBuild(node.Children[index], PolyList, vector2, vector, depth + 1); } } }
public void ExecuteRadianTest() { var exp = new Arcoth(new Number(0.5)); Assert.Equal(MathExtensions.Acoth(0.5), exp.Execute(AngleMeasurement.Radian)); }
///<summary> /// Calculate <a href = "http://en.wikipedia.org/wiki/Great-circle_distance">geodesic /// distance</a> in Meters between this Object and a second Object passed to /// this method using <a href = "http://en.wikipedia.org/wiki/Thaddeus_Vincenty">Thaddeus Vincenty's</a> /// inverse formula See T Vincenty, "<a href = "http://www.ngs.noaa.gov/PUBS_LIB/inverse.pdf">Direct and Inverse /// Solutions of Geodesics on the Ellipsoid with application of nested /// equations</a>", Survey Review, vol XXII no 176, 1975 ///</summary> ///<param name = "location"> /// the destination location </param> ///<param name = "formula"> /// This formula calculates initial bearing (<seealso cref = "INITIAL_BEARING" />), /// final bearing (<seealso cref = "FINAL_BEARING" />) and distance (<seealso cref = "DISTANCE" />). </param> private double VincentyFormula(GeoLocation location, int formula) { double a = 6378137; double b = 6356752.3142; double f = 1 / 298.257223563; // WGS-84 ellipsiod double L = MathExtensions.ToRadians(location.Longitude - Longitude); double U1 = Math.Atan((1 - f) * Math.Tan(MathExtensions.ToRadians(Latitude))); double U2 = Math.Atan((1 - f) * Math.Tan(MathExtensions.ToRadians(location.Latitude))); double sinU1 = Math.Sin(U1), cosU1 = Math.Cos(U1); double sinU2 = Math.Sin(U2), cosU2 = Math.Cos(U2); double lambda = L; double lambdaP = 2 * Math.PI; double iterLimit = 20; double sinLambda = 0; double cosLambda = 0; double sinSigma = 0; double cosSigma = 0; double sigma = 0; double sinAlpha = 0; double cosSqAlpha = 0; double cos2SigmaM = 0; double C; while (Math.Abs(lambda - lambdaP) > 1e-12 && --iterLimit > 0) { sinLambda = Math.Sin(lambda); cosLambda = Math.Cos(lambda); sinSigma = Math.Sqrt((cosU2 * sinLambda) * (cosU2 * sinLambda) + (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda) * (cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); if (sinSigma == 0) { return(0); // co-incident points } cosSigma = sinU1 * sinU2 + cosU1 * cosU2 * cosLambda; sigma = Math.Atan2(sinSigma, cosSigma); sinAlpha = cosU1 * cosU2 * sinLambda / sinSigma; cosSqAlpha = 1 - sinAlpha * sinAlpha; cos2SigmaM = cosSigma - 2 * sinU1 * sinU2 / cosSqAlpha; if (double.IsNaN(cos2SigmaM)) { cos2SigmaM = 0; // equatorial line: cosSqAlpha=0 (§6) } C = f / 16 * cosSqAlpha * (4 + f * (4 - 3 * cosSqAlpha)); lambdaP = lambda; lambda = L + (1 - C) * f * sinAlpha * (sigma + C * sinSigma * (cos2SigmaM + C * cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM))); } if (iterLimit == 0) { return(double.NaN); // formula failed to converge } double uSq = cosSqAlpha * (a * a - b * b) / (b * b); double A = 1 + uSq / 16384 * (4096 + uSq * (-768 + uSq * (320 - 175 * uSq))); double B = uSq / 1024 * (256 + uSq * (-128 + uSq * (74 - 47 * uSq))); double deltaSigma = B * sinSigma * (cos2SigmaM + B / 4 * (cosSigma * (-1 + 2 * cos2SigmaM * cos2SigmaM) - B / 6 * cos2SigmaM * (-3 + 4 * sinSigma * sinSigma) * (-3 + 4 * cos2SigmaM * cos2SigmaM))); double distance = b * A * (sigma - deltaSigma); // initial bearing double fwdAz = MathExtensions.ToDegree(Math.Atan2(cosU2 * sinLambda, cosU1 * sinU2 - sinU1 * cosU2 * cosLambda)); // final bearing double revAz = MathExtensions.ToDegree(Math.Atan2(cosU1 * sinLambda, -sinU1 * cosU2 + cosU1 * sinU2 * cosLambda)); if (formula == DISTANCE) { return(distance); } else if (formula == INITIAL_BEARING) { return(fwdAz); } else if (formula == FINAL_BEARING) { return(revAz); } // should never happpen else { return(double.NaN); } }
/// <summary> /// Gets enemies near target. /// </summary> public IEnumerable <IKillable> GetEnemies(IKiller sender, float x, float z, byte range) { IEnumerable <IKillable> mobs = sender is Mob ? new List <IKillable>() : GetAllMobs(true).Where(m => !m.HealthManager.IsDead && m.HealthManager.IsAttackable && m.CountryProvider.Country != sender.CountryProvider.Country && MathExtensions.Distance(x, m.PosX, z, m.PosZ) <= range); IEnumerable <IKillable> chars = GetAllPlayers(true) .Where(p => !p.HealthManager.IsDead && p.HealthManager.IsAttackable && (p.CountryProvider.Country != sender.CountryProvider.Country || (sender is Character senderPlayer && senderPlayer.DuelManager.IsStarted && p.Id == senderPlayer.DuelManager.OpponentId)) && MathExtensions.Distance(x, p.PosX, z, p.PosZ) <= range); return(mobs.Concat(chars)); }
private Dictionary <Point, ThreatenedCell> GetThreatenSpaces(HashSet <Point> reach, Unit unit) { var threathenedSpaces = new Dictionary <Point, ThreatenedCell>(); int minimumRange = 1; if (unit.Stats[Stats.Range] > 0 && unit.Stats[Stats.Magic] == 0) { minimumRange = 2; } foreach (var pos in reach) { for (int i = unit.Stats[Stats.Range] + 1; i >= minimumRange; i--) { int currPriority = 1000 - MathExtensions.CellDistance(unit.Position, pos); for (int j = i; j != 0; j--) { Point threatPos = new Point(pos.X - j, pos.Y - (i - j)); if (threathenedSpaces.ContainsKey(threatPos) && threathenedSpaces[threatPos].Priority >= currPriority) { continue; } threathenedSpaces[threatPos] = new ThreatenedCell() { Position = threatPos, From = pos, Priority = currPriority }; } for (int j = i; j != 0; j--) { Point threatPos = new Point(pos.X + (i - j), pos.Y - j); if (threathenedSpaces.ContainsKey(threatPos) && threathenedSpaces[threatPos].Priority >= currPriority) { continue; } threathenedSpaces[threatPos] = new ThreatenedCell() { Position = threatPos, From = pos, Priority = currPriority }; } for (int j = i; j != 0; j--) { Point threatPos = new Point(pos.X + j, pos.Y + (i - j)); if (threathenedSpaces.ContainsKey(threatPos) && threathenedSpaces[threatPos].Priority >= currPriority) { continue; } threathenedSpaces[threatPos] = new ThreatenedCell() { Position = threatPos, From = pos, Priority = currPriority }; } for (int j = i; j != 0; j--) { Point threatPos = new Point(pos.X - (i - j), pos.Y + j); if (threathenedSpaces.ContainsKey(threatPos) && threathenedSpaces[threatPos].Priority >= currPriority) { continue; } threathenedSpaces[threatPos] = new ThreatenedCell() { Position = threatPos, From = pos, Priority = currPriority }; } } } foreach (var u in units) { if (u == null) { continue; } if (u.Enemy == unit.Enemy) { threathenedSpaces.Remove(u.Position); } } return(threathenedSpaces); }
/// <summary> /// Calculates this mathematical expression (using gradian). /// </summary> /// <param name="parameters">An object that contains all parameters and functions for expressions.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteGradian(ExpressionParameters parameters) { return(MathExtensions.Acsc((double)m_argument.Execute(parameters)) / Math.PI * 200); }
private void UpdateBolts(bool active = false) { if (MyAPIGateway.Session.Player == null) { return; } //if(Vector3D.Distance(MyAPIGateway.Session.Camera.Position, m_block.PositionComp.GetPosition()) > 50f) if (Vector3D.DistanceSquared(MyAPIGateway.Session.Player.GetPosition(), m_block.PositionComp.GetPosition()) > 50f * 50f) { return; } for (int s = m_activeBolts.Count - 1; s >= 0; s--) { var activeItem = m_activeBolts[s]; activeItem.Position++; if (activeItem.Position >= activeItem.MaxPosition) { m_activeBolts.Remove(activeItem); continue; } } if (m_activeBolts.Count < m_maxBolts) { int numAdd = m_maxBolts - m_activeBolts.Count; for (int r = 0; r < numAdd; r++) { var bolt = LightningBoltEffect.BoltPool[MyUtils.GetRandomInt(0, LightningBoltEffect.BoltPool.Count)]; var boltItem = new LightningBoltInstance(bolt, null, 60 + MyUtils.GetRandomInt(-10, 15)); m_activeBolts.Add(boltItem); } } for (int s = 0; s < m_activeBolts.Count; s++) { var activeItem = m_activeBolts[s]; Vector3D endBoltPosition = m_centerSphere.PositionComp.LocalMatrix.Translation + new Vector3D(0f, 1.5f, 0f); int startPos = 0; int maxPos = activeItem.Bolt.Points.Count; var previousPoint = activeItem.Bolt.Points[startPos]; var color = new Vector4(0.35f, 0.05f, 0.35f, 0.75f); if (active) { color = new Vector4(0.05f, 0.05f, 0.35f, 0.75f); } for (int r = startPos + 1; r < maxPos; r++) { var currentPoint = activeItem.Bolt.Points[startPos + r]; if (previousPoint.Length() > endBoltPosition.Length()) { break; } var startPoint = Vector3D.Transform(currentPoint, MatrixD.CreateRotationY(MathHelper.ToRadians((float)activeItem.Position * 5))); startPoint -= new Vector3D(0f, 1.5f, 0f); startPoint = Vector3D.Transform(startPoint, m_block.WorldMatrix); var endPoint = Vector3D.Transform(previousPoint, MatrixD.CreateRotationY(MathHelper.ToRadians((float)activeItem.Position * 5))); endPoint -= new Vector3D(0f, 1.5f, 0f); endPoint = Vector3D.Transform(endPoint, m_block.WorldMatrix); var dir = Vector3D.Normalize(endPoint - startPoint); var length = (endPoint - startPoint).Length() * 2f; float pulse = MathExtensions.TrianglePulse((float)activeItem.Position, 1f, activeItem.MaxPosition / 2f) + 0.2f; if (activeItem.Position < 10) { pulse = MathExtensions.TrianglePulse((float)activeItem.Position, 1f, 2.5f); } Vector4 diff = color * pulse; float thickness = (0.0125f); MyTransparentGeometry.AddLineBillboard(MyStringId.GetOrCompute("Testfly"), diff, startPoint, dir, (float)length, (float)thickness); previousPoint = currentPoint; } } }
private void Split(OCTPoly poly, Plane p, ref OCTPoly[] newPolys, out int numPolys) { numPolys = 0; var num = p.DotCoordinate(poly.Verts[0]); var num2 = p.DotCoordinate(poly.Verts[1]); var num3 = p.DotCoordinate(poly.Verts[2]); var vector = MathExtensions.NormalFromPoints(poly.Verts[0], poly.Verts[1], poly.Verts[2]); if (((num > 0f) && (num2 > 0f)) && (num3 > 0f)) { newPolys[0] = new OCTPoly(poly.Verts[0], poly.Verts[1], poly.Verts[2]); numPolys = 1; } else if (((num < 0f) && (num2 < 0f)) && (num3 < 0f)) { numPolys = 0; } else if (((num == 0f) && (num2 == 0f)) && (num3 == 0f)) { if (p.DotNormal(vector) >= 0f) { newPolys[0] = new OCTPoly(poly.Verts[0], poly.Verts[1], poly.Verts[2]); numPolys = 1; } else { numPolys = 0; } } else { var vectorArray = new Vector3[4]; var num4 = 0; for (var i = 0; i < 3; i++) { var vector2 = poly.Verts[i]; var vector3 = poly.Verts[((i + 1) > 2) ? 0 : (i + 1)]; var num6 = p.DotCoordinate(vector2); var num7 = p.DotCoordinate(vector3); if (num6 >= 0f) { vectorArray[num4++] = vector2; } if (((num7 <= 0f) && (num6 > 0f)) || ((num7 >= 0f) && (num6 < 0f))) { Vector3 point; if (Intersection.LineSegmentIntersectsPlane(vector2, vector3, p, out point)) { vectorArray[num4++] = point; } } } switch (num4) { case 3: case 4: newPolys[0] = new OCTPoly(vectorArray[0], vectorArray[1], vectorArray[2]); numPolys = 1; if (num4 == 4) { newPolys[1] = new OCTPoly(vectorArray[0], vectorArray[2], vectorArray[3]); numPolys = 2; } break; } } }
public void ExecuteGradianTest() { var exp = new Arcosh(new Number(0.5)); Assert.Equal(MathExtensions.Acosh(0.5) / Math.PI * 200, exp.Execute(AngleMeasurement.Gradian)); }
public void ExecuteTest() { var exp = new Arcsch(new Number(1)); Assert.Equal(MathExtensions.Acsch(1), exp.Execute()); }
/// <summary> /// Calculates this mathematical expression (using gradian). /// </summary> /// <param name="gradian">The calculation result of argument.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteGradian(double gradian) { return(MathExtensions.Cot(gradian * Math.PI / 200)); }
/// <summary> /// Group cells of same color that are near each other. /// </summary> /// <param name="sortedCells"></param> /// <returns></returns> private static List <List <Transform> > GroupConnectedCells(List <Transform> sortedCells) { Queue <Transform> stackedCells = new Queue <Transform>(sortedCells); List <List <Transform> > groupsOfCells = new List <List <Transform> >(); while (stackedCells.Count != 0) { Transform cellToCompare = stackedCells.Dequeue(); List <Transform> currentGroup = null; List <List <Transform> > groupsToRemove = new List <List <Transform> >(); foreach (var cellGroup in groupsOfCells) { foreach (var cell in cellGroup) { if (MathExtensions.SafeComparison(cellToCompare.position.x - 1, cell.position.x) && MathExtensions.SafeComparison(cellToCompare.position.y, cell.position.y) || MathExtensions.SafeComparison(cellToCompare.position.x + 1, cell.position.x) && MathExtensions.SafeComparison(cellToCompare.position.y, cell.position.y) || MathExtensions.SafeComparison(cellToCompare.position.y - 1, cell.position.y) && MathExtensions.SafeComparison(cellToCompare.position.x, cell.position.x) || MathExtensions.SafeComparison(cellToCompare.position.y + 1, cell.position.y) && MathExtensions.SafeComparison(cellToCompare.position.x, cell.position.x)) { if (currentGroup != null) // Merge Group { currentGroup.AddRange(cellGroup); groupsToRemove.Add(cellGroup); } else // Add to a Group { cellGroup.Add(cellToCompare); currentGroup = cellGroup; } break; } } } groupsToRemove.ForEach(x => groupsOfCells.Remove(x)); if (currentGroup == null) { var cellGroup = new List <Transform>(); cellGroup.Add(cellToCompare); groupsOfCells.Add(cellGroup); } } return(groupsOfCells); }
/// <summary> /// Loops through all player characters and creates a dictionary of integer priorities based on the amount of threat /// a character has generated. /// <para>Priority is based on the threat a character generates compared to the rest of it's squad.</para> /// </summary> /// <returns></returns> protected virtual Dictionary <Character, int> EvaluateEnemies() { var enemies = new List <Character>(LivingPlayerCharacters); var characterPriorities = new Dictionary <Character, int>(); int median = MathExtensions.GetMedian(enemies.Select(enemy => enemy.Threat).ToList()); if (enemies.Count() == 2) { if (enemies[0].Threat > enemies[1].Threat) { characterPriorities[enemies[0]] = 2; characterPriorities[enemies[1]] = 1; } else { characterPriorities[enemies[1]] = 2; characterPriorities[enemies[0]] = 1; } foreach (var enemy in enemies) { int percentHealth = (int)(((float)enemy.CurrentHealth) / enemy.CurrentMaxHealth * 100); // If percentage of health is less than 25%, increase threat level by 2 if (percentHealth <= 25) { characterPriorities[enemy] += 2; } else if (percentHealth <= 50) { characterPriorities[enemy] += 1; } } } else { foreach (var enemy in enemies) { int threatAsMedianPercentage = (int)(((float)enemy.Threat) / median * 100); // If threat is 50% higher than the median, threat level is 3 if (threatAsMedianPercentage >= 150) { characterPriorities[enemy] = 3; } // If threat is 20% higher than the median, threat level is 2 else if (threatAsMedianPercentage >= 120) { characterPriorities[enemy] = 2; } else { characterPriorities[enemy] = 1; } int percentHealth = (int)(((float)enemy.CurrentHealth) / enemy.CurrentMaxHealth * 100); // If percentage of health is less than 25%, increase threat level by 2 if (percentHealth <= 25) { characterPriorities[enemy] += 2; } else if (percentHealth <= 50) { characterPriorities[enemy] += 1; } } } return(characterPriorities); }
/// <summary> /// Mark cells on top of the cellPosition that are floating in the air. /// </summary> /// <param name="allCells"></param> /// <param name="cellPosition">starting position where cells are searched for</param> private void MarkFlyingCell(List <Transform> allCells, Vector2 cellPosition) { List <Transform> upperCell = allCells.Where(c => cellPosition.y < c.position.y && MathExtensions.SafeComparison(cellPosition.x, c.position.x)).OrderBy(c => c.position.y).ToList(); if (upperCell.Count > 0 && upperCell[0].position.y > 1) { upperCell.ForEach(c => { c.GetComponent <BlockAnnotation>().UpInTheAir = true; c.GetComponent <BlockController>().ChangeText("L"); }); } }
public void ExecuteDegreeTest() { var exp = new Csc(new Number(1)); Assert.Equal(MathExtensions.Csc(Math.PI / 180), exp.Execute(AngleMeasurement.Degree)); }
/// <summary> /// A method that calculates UTC sunset as well as any time based on an angle /// above or below sunset. This abstract method is implemented by the classes /// that extend this class. /// </summary> /// <param name="astronomicalCalendar">Used to calculate day of year.</param> /// <param name="zenith">the azimuth below the vertical zenith of 90°;. For sunset /// typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for the /// calculation uses geometric zenith of 90°; and /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for /// solar refraction and the sun's radius. Another example would /// be <see cref="AstronomicalCalendar.GetEndNauticalTwilight"/> that /// passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to this /// method.</param> /// <param name="adjustForElevation"></param> /// <returns> /// The UTC time of sunset in 24 hour format. 5:45:00 AM will return /// 5.75.0. If an error was encountered in the calculation (expected /// behavior for some locations such as near the poles, /// <seealso cref="Double.NaN"/> will be returned. /// </returns> public override double GetUtcSunset(IAstronomicalCalendar astronomicalCalendar, double zenith, bool adjustForElevation) { // zenith = adjustZenithForElevation(astronomicalCalendar, zenith, // geoLocation.getElevation()); // double elevationAdjustment = this.getElevationAdjustment(zenith, // geoLocation.getElevation()); // double refractionAdjustment = this.getRefraction(zenith); // zenith = zenith + elevationAdjustment + refractionAdjustment; if (adjustForElevation) { zenith = AdjustZenith(zenith, astronomicalCalendar.DateWithLocation.Location.Elevation); } else { zenith = AdjustZenith(zenith, 0); } // step 1: First calculate the day of the year // int calendarDayOfYear = calelendar.DAY_OF_YEAR; // int N=theday - date(1,1,theday.year()) + 1; int N = astronomicalCalendar.DateWithLocation.Date.DayOfYear; // step 2: convert the longitude to hour value and calculate an // approximate time double lngHour = astronomicalCalendar.DateWithLocation.Location.Longitude / 15; double t = N + ((18 - lngHour) / 24); // step 3: calculate the sun's mean anomaly double M = (0.9856 * t) - 3.289; // step 4: calculate the sun's true longitude double L = M + (1.916 * Math.Sin(MathExtensions.ToRadians(M))) + (0.020 * Math.Sin(MathExtensions.ToRadians(2 * M))) + 282.634; while (L < 0) { double Lx = L + 360; L = Lx; } while (L >= 360) { double Lx = L - 360; L = Lx; } // step 5a: calculate the sun's right ascension double RA = MathExtensions.ToDegree(Math.Atan(0.91764 * Math.Tan(MathExtensions.ToRadians(L)))); while (RA < 0) { double RAx = RA + 360; RA = RAx; } while (RA >= 360) { double RAx = RA - 360; RA = RAx; } // step 5b: right ascension value needs to be in the same quadrant as L double Lquadrant = Math.Floor(L / 90) * 90; double RAquadrant = Math.Floor(RA / 90) * 90; RA = RA + (Lquadrant - RAquadrant); // step 5c: right ascension value needs to be converted into hours RA /= 15; // step 6: calculate the sun's declination double sinDec = 0.39782 * Math.Sin(MathExtensions.ToRadians(L)); double cosDec = Math.Cos(Math.Asin(sinDec)); // step 7a: calculate the sun's local hour angle double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) - (sinDec * Math.Sin(MathExtensions.ToRadians(astronomicalCalendar.DateWithLocation.Location.Latitude)))) / (cosDec * Math.Cos(MathExtensions.ToRadians(astronomicalCalendar.DateWithLocation.Location.Latitude))); // the following line would throw an Exception if the sun never set. // this is not needed since the calculation will return a Double.NaN // if (cosH < -1) throw new ZmanimException("doesnthappen"); // step 7b: finish calculating H and convert into hours double H = MathExtensions.ToDegree(Math.Acos(cosH)); H = H / 15; // step 8: calculate local mean time double T = H + RA - (0.06571 * t) - 6.622; // step 9: convert to UTC double UT = T - lngHour; while (UT < 0) { double UTx = UT + 24; UT = UTx; } while (UT >= 24) { double UTx = UT - 24; UT = UTx; } return(UT); }
/// <summary> /// Calculates this mathematical expression (using radian). /// </summary> /// <param name="parameters">An object that contains all parameters and functions for expressions.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteRadian(ExpressionParameters parameters) { return(MathExtensions.Csc((double)m_argument.Execute(parameters))); }
/// <summary> /// A method that calculates UTC sunrise as well as any time based on an /// angle above or below sunrise. This abstract method is implemented by the /// classes that extend this class. /// </summary> /// <param name="astronomicalCalendar">Used to calculate day of year.</param> /// <param name="zenith">the azimuth below the vertical zenith of 90 degrees. for /// sunrise typically the <see cref="AstronomicalCalculator.AdjustZenith">zenith</see> used for /// the calculation uses geometric zenith of 90°; and /// <see cref="AstronomicalCalculator.AdjustZenith">adjusts</see> this slightly to account for /// solar refraction and the sun's radius. Another example would /// be <see cref="AstronomicalCalendar.GetBeginNauticalTwilight"/> /// that passes <see cref="AstronomicalCalendar.NAUTICAL_ZENITH"/> to /// this method.</param> /// <param name="adjustForElevation"></param> /// <returns> /// The UTC time of sunrise in 24 hour format. 5:45:00 AM will return /// 5.75.0. If an error was encountered in the calculation (expected /// behavior for some locations such as near the poles, /// <see cref="Double.NaN"/> will be returned. /// </returns> public override double GetUtcSunrise(IAstronomicalCalendar astronomicalCalendar, double zenith, bool adjustForElevation) { // zenith = adjustZenithForElevation(astronomicalCalendar, zenith, // geoLocation.getElevation()); // double elevationAdjustment = this.getElevationAdjustment(zenith, // geoLocation.getElevation()); // double refractionAdjustment = this.getRefraction(zenith); // zenith = zenith + elevationAdjustment + refractionAdjustment; if (adjustForElevation) { zenith = AdjustZenith(zenith, astronomicalCalendar.DateWithLocation.Location.Elevation); } else { zenith = AdjustZenith(zenith, 0); } // step 1: First calculate the day of the year // NOT NEEDED in this implementation // step 2: convert the longitude to hour value and calculate an // approximate time double lngHour = astronomicalCalendar.DateWithLocation.Location.Longitude / 15; double t = astronomicalCalendar.DateWithLocation.Date.DayOfYear + ((6 - lngHour) / 24); // use 18 for // sunset instead // of 6 // step 3: calculate the sun's mean anomaly double m = (0.9856 * t) - 3.289; // step 4: calculate the sun's true longitude double l = m + (1.916 * Math.Sin(MathExtensions.ToRadians(m))) + (0.020 * Math.Sin(MathExtensions.ToRadians(2 * m))) + 282.634; while (l < 0) { double Lx = l + 360; l = Lx; } while (l >= 360) { double Lx = l - 360; l = Lx; } // step 5a: calculate the sun's right ascension double RA = MathExtensions.ToDegree(Math.Atan(0.91764 * Math.Tan(MathExtensions.ToRadians(l)))); while (RA < 0) { double RAx = RA + 360; RA = RAx; } while (RA >= 360) { double RAx = RA - 360; RA = RAx; } // step 5b: right ascension value needs to be in the same quadrant as L double lQuadrant = Math.Floor(l / 90) * 90; double raQuadrant = Math.Floor(RA / 90) * 90; RA = RA + (lQuadrant - raQuadrant); // step 5c: right ascension value needs to be converted into hours RA /= 15; // step 6: calculate the sun's declination double sinDec = 0.39782 * Math.Sin(MathExtensions.ToRadians(l)); double cosDec = Math.Cos(Math.Asin(sinDec)); // step 7a: calculate the sun's local hour angle double cosH = (Math.Cos(MathExtensions.ToRadians(zenith)) - (sinDec * Math.Sin(MathExtensions.ToRadians(astronomicalCalendar.DateWithLocation.Location.Latitude)))) / (cosDec * Math.Cos(MathExtensions.ToRadians(astronomicalCalendar.DateWithLocation.Location.Latitude))); // the following line would throw an Exception if the sun never rose. // this is not needed since the calculation will return a Double.NaN // if (cosH > 1) throw new Exception("doesnthappen"); // FOR SUNSET use the following instead of the above if statement. // if (cosH < -1) // step 7b: finish calculating H and convert into hours double H = 360 - MathExtensions.ToDegree(Math.Acos(cosH)); // FOR SUNSET remove "360 - " from the above H = H / 15; // step 8: calculate local mean time double T = H + RA - (0.06571 * t) - 6.622; // step 9: convert to UTC double UT = T - lngHour; while (UT < 0) { double UTx = UT + 24; UT = UTx; } while (UT >= 24) { double UTx = UT - 24; UT = UTx; } return(UT); }
/// <summary> /// Calculates this mathematical expression (using gradian). /// </summary> /// <param name="gradian">The calculation result of argument.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteGradian(double gradian) { return(MathExtensions.Asech(gradian) / Math.PI * 200); }
static Vector3?GetPointAtPosition(Vector2 mousePosition, Rect dragArea) { UnitySceneExtensions.Grid.HoverGrid = null; if (s_CurrentPointIndex == 0) { s_StartIntersection = ChiselClickSelectionManager.GetPlaneIntersection(mousePosition, dragArea); if (s_StartIntersection != null && s_StartIntersection.plane.normal.sqrMagnitude > 0) // TODO: figure out how this could happen { // TODO: try to cache this .. var activeGridUp = UnitySceneExtensions.Grid.ActiveGrid.Up; var activeGridForward = UnitySceneExtensions.Grid.ActiveGrid.Forward; var activeGridCenter = UnitySceneExtensions.Grid.ActiveGrid.Center; var surfaceGridPlane = s_StartIntersection.plane; var surfaceGridUp = surfaceGridPlane.normal; var surfaceGridForward = MathExtensions.CalculateBinormal(surfaceGridUp); var activeGridFromWorldRotation = Quaternion.LookRotation(activeGridUp, activeGridForward); var worldFromActiveGridRotation = Quaternion.Inverse(activeGridFromWorldRotation); var surfaceGridFromWorldRotation = Quaternion.LookRotation(surfaceGridUp, surfaceGridForward); var activeGridToSurfaceGridRotation = surfaceGridFromWorldRotation * worldFromActiveGridRotation; // Make sure the center of the new grid is as close to the active grid center as possible Vector3 surfaceGridCenter = activeGridCenter; var forwardRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.up); var backRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.down); var leftRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.left); var rightRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.right); var upRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.forward); var downRay = new Ray(activeGridCenter, worldFromActiveGridRotation * Vector3.back); var bestDist = float.PositiveInfinity; float dist; if (surfaceGridPlane.SignedRaycast(forwardRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = forwardRay.GetPoint(dist); } } if (surfaceGridPlane.SignedRaycast(backRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = backRay.GetPoint(dist); } } if (surfaceGridPlane.SignedRaycast(leftRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = leftRay.GetPoint(dist); } } if (surfaceGridPlane.SignedRaycast(rightRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = rightRay.GetPoint(dist); } } if (bestDist > 100000) // prefer rays on the active-grid, only go up/down from the active-grid when we have no other choice { if (surfaceGridPlane.SignedRaycast(upRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = upRay.GetPoint(dist); } } if (surfaceGridPlane.SignedRaycast(downRay, out dist)) { var abs_dist = Mathf.Abs(dist); if (abs_dist < bestDist) { bestDist = abs_dist; surfaceGridCenter = downRay.GetPoint(dist); } } } // TODO: try to snap the new surface grid point in other directions on the active-grid? (do we need to?) s_Transform = Matrix4x4.TRS(surfaceGridCenter - activeGridCenter, activeGridToSurfaceGridRotation, Vector3.one) * UnitySceneExtensions.Grid.ActiveGrid.GridToWorldSpace; s_InvTransform = s_Transform.inverse; s_Snapping2D.Initialize(new UnitySceneExtensions.Grid(s_Transform), mousePosition, s_StartIntersection.point, UnityEditor.Handles.matrix); } } if (s_StartIntersection != null) { if (!dragArea.Contains(mousePosition)) { return(null); } if (s_Snapping2D.DragTo(mousePosition, SnappingMode.Always)) { UnitySceneExtensions.Grid.HoverGrid = s_Snapping2D.WorldSlideGrid; return(s_Snapping2D.WorldSnappedPosition); } } return(null); }
/// <summary> /// Calculates this mathematical expression (using radian). /// </summary> /// <param name="radian">The calculation result of argument.</param> /// <returns> /// A result of the calculation. /// </returns> /// <seealso cref="ExpressionParameters" /> protected override double ExecuteRadian(double radian) { return(MathExtensions.Acot(radian)); }
public void ExecuteDegreeTest() { var exp = new Arcosh(new Number(0.5)); Assert.Equal(MathExtensions.Acosh(0.5) / Math.PI * 180, exp.Execute(AngleMeasurement.Degree)); }
public void TurnToward(Vector3 position, Rotation priority1, Rotation priority2, Rotation? priority3, MathExtensions.QuaternionInterpolationType interpolateType, float interpolateRate, Vector3? up = null) { if (priority1 == priority2 || priority1 == priority3 || priority2 == priority3) { Debug.LogError("Priorities must be unique."); return; } TurnToward(position, priority1, interpolateType, interpolateRate, up); TurnToward(position, priority2, interpolateType, interpolateRate, up); if (priority3 != null) TurnToward(position, priority3.Value, interpolateType, interpolateRate, up); }
public void TestCubicSolve() { double result1 = MathExtensions.SolveReducedCubicEquation(2, 2)[0]; Assert.AreEqual(Math.Round(result1, 2), -0.77); }