private QTNode GetSameLevelBorder(int dir) { List <QTNode> nodeList = QTManager.Instance.activeTerrain.allNodeListArray[lodLevel]; Vector3 target = Vector3.zero; switch (dir) { case 0: target = center + new Vector3(0f, 0f, length); break; case 1: target = center + new Vector3(length, 0f, 0f); break; case 2: target = center + new Vector3(0f, 0f, -length); break; case 3: target = center + new Vector3(-length, 0f, 0f); break; } for (int i = 0; i < nodeList.Count; i++) { if (MathExtra.ApproEquals(nodeList [i].center.x, target.x) && MathExtra.ApproEquals(nodeList [i].center.z, target.z)) { return(nodeList [i]); } } return(null); }
public Vector2 Move(Vector2 ori, float rad, Vector2 dir) { activeObstacleList.Clear(); for (int i = 0; i < dynamicObstacleList.Count; i++) { if ((dynamicObstacleList [i].GetOri() - ori).sqrMagnitude <= dynamicObstacleList [i].GetSqrRange() + rad * rad + dir.sqrMagnitude + 1f) { activeObstacleList.Add(dynamicObstacleList [i]); } } Vector2 newPos = ori + dir; float dist = 0f; for (int i = 0; i < 3; i++) { dist = QueryWorld(newPos); if (dist >= rad) { break; } newPos = ori + MathExtra.FastNormalize(newPos + QueryNormal(newPos) * (rad - dist) - ori) * 4f * Time.deltaTime; } if (Vector2.Dot(newPos - ori, dir) < 0f) { return(ori); } return(newPos); }
private void GetSunriseSunset() { if (double.Parse(txtLatitude.Text, CultureInfo.InvariantCulture) == 0 && double.Parse(txtLongitude.Text, CultureInfo.InvariantCulture) == 0) { lblSunriseSunset.Text = "No City/Location set."; return; } int offsetMins;// = 0; offsetMins = int.Parse(txtOffsetMins.Text, CultureInfo.InvariantCulture); parentForm.GetSunriseSunset(double.Parse(txtLatitude.Text, CultureInfo.InvariantCulture), double.Parse(txtLongitude.Text, CultureInfo.InvariantCulture)); DateTime sunrise = parentForm.sunrise; DateTime sunset = parentForm.sunset; sunrise = sunrise.AddMinutes(offsetMins); sunset = sunset.AddMinutes(offsetMins); // round mins to nearest 5 double sunriseMins = sunrise.Minute; double sunsetMins = sunset.Minute; sunriseMins = MathExtra.RoundCustom(sunriseMins, 5); sunsetMins = MathExtra.RoundCustom(sunsetMins, 5); if (sunriseMins > 55) { sunriseMins = 55; } if (sunsetMins > 55) { sunsetMins = 55; } parentForm.sunrise = new DateTime(sunrise.Year, sunrise.Month, sunrise.Day, sunrise.Hour, (int)(sunriseMins), 0); parentForm.sunset = new DateTime(sunset.Year, sunset.Month, sunset.Day, sunset.Hour, (int)(sunsetMins), 0); lblSunriseSunset.Text = ("Sunrise @ " + sunrise.ToString("HH:mm", CultureInfo.InvariantCulture) + "\nSunset @ " + sunset.ToString("HH:mm", CultureInfo.InvariantCulture)); if (parentForm.settings.UseSunriseSunset) { parentForm.settings.LightSunriseTime = parentForm.sunrise; parentForm.settings.DarkSunsetTime = parentForm.sunset; // Set the Light and Dark Times SetLightDarkTimeControls(); if (!parentForm.applyingSettings) { // if not on NULL ISLAND (0,0) //https://en.wikipedia.org/wiki/Null_Island if ((double.Parse(txtLatitude.Text, CultureInfo.InvariantCulture) == 0 && double.Parse(txtLongitude.Text, CultureInfo.InvariantCulture) == 0) == false) { parentForm.AdjustDesktopImages(); //(false); } } } }
private QTNode FindNearest(QTNode root, Vector3 pos) { QTNode node = root.GetChild(0); if (node == null || root.lodLevel == this.lodLevel) { return(root); } float dis; float disTemp; dis = MathExtra.FastDis(node.center, pos); disTemp = MathExtra.FastDis(root.GetChild(1).center, pos); if (disTemp < dis) { dis = disTemp; node = root.GetChild(1); } disTemp = MathExtra.FastDis(root.GetChild(2).center, pos); if (disTemp < dis) { dis = disTemp; node = root.GetChild(2); } disTemp = MathExtra.FastDis(root.GetChild(3).center, pos); if (disTemp < dis) { dis = disTemp; node = root.GetChild(3); } return(FindNearest(node, pos)); }
public override IEnumerable <PathfinderLink> GetNeighbors() { //return Neighbors; int minX = Map.WrapsX ? X - 1 : Math.Max(0, X - 1); int minY = Map.WrapsY ? Y - 1 : Math.Max(0, Y - 1); int maxX = Map.WrapsX ? X + 1 : Math.Min(Map.SizeX - 1, X + 1); int maxY = Map.WrapsY ? Y + 1 : Math.Min(Map.SizeY - 1, Y + 1); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { int x2 = Map.WrapsX ? MathExtra.Wrap(x, Map.SizeX) : x; int y2 = Map.WrapsY ? MathExtra.Wrap(y, Map.SizeY) : y; PathfinderTile tile = Map.TileGrid[x2, y2]; if (tile != this) { double cost = tile.GetCost(); bool isDiagonal = (Math.Abs(X - x) + Math.Abs(Y - y) == 2); if (isDiagonal) { cost *= Math.Sqrt(2); } //Neighbors.Add(new SimpleLink(tile, cost)); yield return(new SimpleLink(tile, cost)); } } } }
public float ComputeEdgeCollapseCost(PRVertex u, PRVertex v) { float edgeLength = MathExtra.GetV3L(u.pos - v.pos); float curvature = 0f; List <PRTriangle> sides = new List <PRTriangle> (); for (int i = 0; i < u.face.Count; i++) { if (u.face [i].HasVertex(v)) { sides.Add(u.face[i]); } } for (int i = 0; i < u.face.Count; i++) { float mincurv = 1f; for (int j = 0; j < sides.Count; j++) { float dotprod = Vector3.Dot(u.face [i].normal, sides [j].normal); mincurv = Mathf.Min(mincurv, (1f - dotprod) * 0.5f); } curvature = Mathf.Max(curvature, mincurv); } return(edgeLength * curvature); }
void Awake() { width = transform.localScale.x; height = transform.localScale.y; _upRightVertex = new Vector2(width * 0.5f, height * 0.5f); sqrRange = new Vector2(width * 0.5f, height * 0.5f).sqrMagnitude; _range = MathExtra.FastSqrt(sqrRange); }
/// <summary> /// 在预计算中获取点到碰撞体的最近距离 /// </summary> public float ClosestDisOnBounds(Vector2 point, bool debug = false) { if (DistanceFields.Instance.selfObs == this) { return(100f); } return(Mathf.Max(MathExtra.GetV2L(point - (Vector2)transform.position) - _range, 0f)); }
// Update is called once per frame public void Update() { if (MathExtra.FastDis(playerTrans.position, oldPos) >= 1f) { Execute(); oldPos = playerPos; } }
public void Update(GameTime gameTime) { Position += Velocity * (float)gameTime.ElapsedGameTime.TotalSeconds; Heading += AngularVelocity * (float)gameTime.ElapsedGameTime.TotalSeconds; if (TurnAssist) { AngularMomentum = MathExtra.Reduce(AngularMomentum, 1000f); } }
public Vector2 QueryNormal(Vector2 worldPos) { float left = GetPixelBilinear(worldPos + new Vector2(-0.1f, 0f)); float right = GetPixelBilinear(worldPos + new Vector2(0.1f, 0f)); float top = GetPixelBilinear(worldPos + new Vector2(0f, 0.1f)); float bottom = GetPixelBilinear(worldPos + new Vector2(0f, -0.1f)); float x = (left - right) * 0.5f; float y = (bottom - top) * 0.5f; return(MathExtra.FastNormalize(new Vector2(x, y))); }
/// <summary> /// 在预计算中获取点到碰撞体的最近距离 /// </summary> public float ClosestDisOnBounds(Vector2 point) { transform.localScale = Vector3.one; Vector2 _point = (Vector2)transform.InverseTransformPoint(new Vector3(point.x, point.y, 0f)); transform.localScale = _oldScale; _point = new Vector2(Mathf.Abs(_point.x), Mathf.Abs(_point.y)); Vector2 v = _point - _center; Vector2 h = _upRightVertex - _center; Vector2 u = v - h; u = new Vector2(Mathf.Max(u.x, 0f), Mathf.Max(u.y, 0f)); return(MathExtra.GetV2L(u)); }
private void Execute() { //playerPos = playerTrans.position; float dis = MathExtra.FastSqrt(playerTrans.position.sqrMagnitude); playerPos = playerTrans.position / dis * Mathf.Max((dis - activePlanet.sphereRadius * activePlanet.heightScale), activePlanet.sphereRadius); for (int i = 0; i < activePlanet.quadList.Count; i++) { activeTerrain = activePlanet.quadList[i]; activeTerrain.Execute(); activeTerrain.TryGenerateBorder(); activeTerrain.CalculateMesh(); activeTerrain.UpdateMesh(); } }
void Update() { slowTimer -= Time.deltaTime; if (slowTimer <= 0f) { speedMultiplier = 1f; } float angle = MathExtra.Vector2ToDiamondAngle(transform.position.y - target.position.y, transform.position.x - target.position.x); Vector2 movement = MathExtra.DiamondAngleToVector2(angle); Move(-movement.x * speed * speedMultiplier, -movement.y * speed * speedMultiplier); }
public QTNode FindBorder(QTNode node, int dir) { nodeList = null; tNode = null; for (int i = node.lodLevel + 2; i < activeTerrain.maxLodLevel; i++) { nodeList = activeTerrain.activeNodeListArray [i]; for (int m = 0; m < nodeList.Count; m++) { tNode = nodeList[m]; switch (dir) { case 0: if (MathExtra.ApproEquals(node.center.z + node.length * 0.5f, tNode.center.z - tNode.length * 0.5f) && (node.center.x > tNode.center.x - tNode.length * 0.5f) && (node.center.x < tNode.center.x + tNode.length * 0.5f)) { return(tNode); } break; case 1: if (MathExtra.ApproEquals(node.center.x + node.length * 0.5f, tNode.center.x - tNode.length * 0.5f) && (node.center.z > tNode.center.z - tNode.length * 0.5f) && (node.center.z < tNode.center.z + tNode.length * 0.5f)) { return(tNode); } break; case 2: if (MathExtra.ApproEquals(node.center.z - node.length * 0.5f, tNode.center.z + tNode.length * 0.5f) && (node.center.x > tNode.center.x - tNode.length * 0.5f) && (node.center.x < tNode.center.x + tNode.length * 0.5f)) { return(tNode); } break; case 3: if (MathExtra.ApproEquals(node.center.x - node.length * 0.5f, tNode.center.x + tNode.length * 0.5f) && (node.center.z > tNode.center.z - tNode.length * 0.5f) && (node.center.z < tNode.center.z + tNode.length * 0.5f)) { return(tNode); } break; } } } return(null); }
public void SetUpCollision(int tID, int x, int y) { triangle[tID] = new Tri(); triangle[tID].p1 = GetPosition(x, y); triangle[tID].p2 = GetPosition(x, y + 1); triangle[tID].p3 = GetPosition(x + 1, y); triangle[tID].normal = MathExtra.GetNormal(triangle[tID].p1, triangle[tID].p2, triangle[tID].p3); triangle[tID].id = tID; triangle[tID + 1] = new Tri(); triangle[tID + 1].p1 = GetPosition(x + 1, y); triangle[tID + 1].p2 = GetPosition(x, y + 1); triangle[tID + 1].p3 = GetPosition(x + 1, y + 1); triangle[tID + 1].normal = MathExtra.GetNormal(triangle[tID + 1].p1, triangle[tID + 1].p2, triangle[tID + 1].p3); triangle[tID + 1].id = tID + 1; }
/// <summary> /// 在预计算中获取点到碰撞体的最近距离 /// </summary> public float ClosestDisOnBounds(Vector2 point, bool debug = false) { if ((point - (Vector2)transform.position).sqrMagnitude > Mathf.Pow(_range + DistanceFields.Instance.radius, 2f)) { return(100f); } Vector2 _point = (Vector2)transform.InverseTransformPoint(new Vector3(point.x, point.y, 0f)); _point = new Vector2(_point.x * transform.localScale.x, _point.y * transform.localScale.y); _point = new Vector2(Mathf.Abs(_point.x), Mathf.Abs(_point.y)); Vector2 v = _point; Vector2 h = _upRightVertex; Vector2 u = v - h; u = new Vector2(Mathf.Max(u.x, 0f), Mathf.Max(u.y, 0f)); return(MathExtra.GetV2L(u)); }
public float?Intersect(ref Ray ray) { List <int> triangles = new List <int>(); quadTree.GetTriangles(ref ray, ref triangles); float rayLength; foreach (int triID in triangles) { Tri tri = triangle[triID]; if (MathExtra.Intersects(ray, tri.p1, tri.p2, tri.p3, tri.normal, false, true, out rayLength)) { return(rayLength); } } return(null); }
public DefaultOperators() { operators = new List <Operator> { new("^", 2, 3, (p, a, b) => Math.Pow(p.EvalTree(a), p.EvalTree(b))), new("+", 2, 6, (p, a, b) => p.EvalTree(a) + p.EvalTree(b)), new("-", 2, 6, (p, a, b) => p.EvalTree(a) - p.EvalTree(b)), new("/", 2, 4, (p, a, b) => p.EvalTree(a) / p.EvalTree(b)), new("*", 2, 4, (p, a, b) => p.EvalTree(a) * p.EvalTree(b)), new("cos", 1, 2, (p, a, b) => Math.Cos(p.EvalTree(a))), new("sin", 1, 2, (p, a, b) => Math.Sin(p.EvalTree(a))), new("exp", 1, 2, (p, a, b) => Math.Exp(p.EvalTree(a))), new("ln", 1, 2, (p, a, b) => Math.Log(p.EvalTree(a))), new("tan", 1, 2, (p, a, b) => Math.Tan(p.EvalTree(a))), new("acos", 1, 2, (p, a, b) => Math.Acos(p.EvalTree(a))), new("asin", 1, 2, (p, a, b) => Math.Asin(p.EvalTree(a))), new("atan", 1, 2, (p, a, b) => Math.Atan(p.EvalTree(a))), new("cosh", 1, 2, (p, a, b) => Math.Cosh(p.EvalTree(a))), new("sinh", 1, 2, (p, a, b) => Math.Sinh(p.EvalTree(a))), new("tanh", 1, 2, (p, a, b) => Math.Tanh(p.EvalTree(a))), new("sqrt", 1, 2, (p, a, b) => Math.Sqrt(p.EvalTree(a))), new("cotan", 1, 2, (p, a, b) => 1 / Math.Tan(p.EvalTree(a))), new("fpart", 1, 2, (p, a, b) => MathExtra.Fpart(p.EvalTree(a))), new("acotan", 1, 2, (p, a, b) => Math.PI / 2 - Math.Atan(p.EvalTree(a))), new("round", 1, 2, (p, a, b) => Math.Round(p.EvalTree(a))), new("ceil", 1, 2, (p, a, b) => Math.Ceiling(p.EvalTree(a))), new("floor", 1, 2, (p, a, b) => Math.Floor(p.EvalTree(a))), new("fac", 1, 2, (p, a, b) => MathExtra.Fac(p.EvalTree(a))), new("sfac", 1, 2, (p, a, b) => MathExtra.Sfac(p.EvalTree(a))), new("abs", 1, 2, (p, a, b) => Math.Abs(p.EvalTree(a))), new("log", 1, 2, (p, a, b) => Math.Log10(p.EvalTree(a))), new("%", 2, 4, (p, a, b) => p.EvalTree(a) % p.EvalTree(b)), new(">", 2, 7, (p, a, b) => p.EvalTree(a) > p.EvalTree(b) ? 1 : 0), new("<", 2, 7, (p, a, b) => p.EvalTree(a) < p.EvalTree(b) ? 1 : 0), new("&&", 2, 8, (p, a, b) => Math.Abs(p.EvalTree(a) - 1) <= double.Epsilon && Math.Abs(p.EvalTree(b) - 1) <= double.Epsilon ? 1 : 0), new("==", 2, 7, (p, a, b) => Math.Abs(p.EvalTree(a) - p.EvalTree(b)) <= double.Epsilon ? 1 : 0), new("!=", 2, 7, (p, a, b) => Math.Abs(p.EvalTree(a) - p.EvalTree(b)) > double.Epsilon ? 1 : 0), new("||", 2, 9, (p, a, b) => Math.Abs(p.EvalTree(a) - 1) <= double.Epsilon || Math.Abs(p.EvalTree(b) - 1) <= double.Epsilon ? 1 : 0), new("!", 1, 1, (p, a, b) => !(Math.Abs(p.EvalTree(a) - 1) <= double.Epsilon) ? 1 : 0), new(">=", 2, 7, (p, a, b) => p.EvalTree(a) >= p.EvalTree(b) ? 1 : 0), new("<=", 2, 7, (p, a, b) => p.EvalTree(a) <= p.EvalTree(b) ? 1 : 0) }; }
/// <summary> /// Recalculate the normals of a mesh based on an angle threshold. This takes /// into account distinct vertices that have the same position. /// </summary> /// <param name="mesh"></param> /// <param name="angle"> /// The smoothing angle. Note that triangles that already share /// the same vertex will be smooth regardless of the angle! /// </param> public static void RecalculateHardNormals(this Mesh mesh) { var vertices = mesh.vertices; Vector3 p1; Vector3 p2; Vector3[] normals = new Vector3[vertices.Length]; for (var i = 0; i < vertices.Length; i += 3) { // Calculate the normal of the triangle p1 = vertices[i + 1] - vertices[i]; p2 = vertices[i + 2] - vertices[i]; normals[i] = normals[i + 1] = normals[i + 2] = MathExtra.FastNormalize(Vector3.Cross(p1, p2)); } // Each entry in the dictionary represents a unique vertex position. mesh.normals = normals; }
private void Set(int x, int y, double value) { if (_WrapX) { x = MathExtra.Wrap(x, _SizeX); } else { x = MathHelper.Clamp(x, 0, _SizeX - 1); } if (_WrapY) { y = MathExtra.Wrap(y, _SizeY); } else { y = MathHelper.Clamp(y, 0, _SizeY - 1); } Heightmap[x, y] = value; }
private IEnumerable <Color> GetColors(Color[] data, int centerX, int centerY) { int minX = centerX - 1; int maxX = centerX + 1; int minY = Math.Max(0, centerY - 1); int maxY = Math.Min(Height - 1, centerY + 1); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { int d = Math.Abs(centerX - x) + Math.Abs(centerY - y); if (d < 2) { int x2 = MathExtra.Wrap(x, Width); yield return(data[x2 + y * Width]); } } } }
private double Get(int x, int y) { if (_WrapX) { x = MathExtra.Wrap(x, _SizeX); } else { x = MathHelper.Clamp(x, 0, _SizeX - 1); } if (_WrapY) { y = MathExtra.Wrap(y, _SizeY); } else { y = MathHelper.Clamp(y, 0, _SizeY - 1); } return(Heightmap[x, y]); }
private void CarveTrench(int x, int y, int radius) { int minX = x - radius; int maxX = x + radius; int minY = Math.Max(y - radius, 0); int maxY = Math.Min(y + radius, SizeY - 1); int radiusSquared = radius * radius; for (int x2 = minX; x2 <= maxX; x2++) { for (int y2 = minY; y2 <= maxY; y2++) { int dx = x2 - x; int dy = y2 - y; int distanceSquared = dx * dx + dy * dy; if (distanceSquared < radiusSquared) { Altitude[MathExtra.Wrap(x2, SizeX), y2] -= AltitudeScale / 64; } } } }
public void InitializeNeighbors() { int minX = X - 1; int minY = Math.Max(0, Y - 1); int maxX = X + 1; int maxY = Math.Min(Surface.SizeY - 1, Y + 1); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { int x2 = MathExtra.Wrap(x, Surface.SizeX); Tile tile = Surface.TileGrid[x2, y]; if (tile != this) { bool diagonal = (Math.Abs(X - x) + Math.Abs(Y - y) == 2); int cost = diagonal ? 1500 : 1000; Neighbors.Add(new SimpleLink(tile, cost)); } } } }
private Point ScreenToWorld(Point position) { position += Camera.PositionPoint; position.X /= TileSize; position.Y /= TileSize; position.X = MathExtra.Wrap(position.X, Surface.SizeX); position.Y = MathHelper.Clamp(position.Y, 0, Surface.SizeY - 1); /* * if (position.X < 0) * position.X += position.X % Surface.SizeX; * else if (position.X >= Surface.SizeX) * position.X %= Surface.SizeX; * if (position.Y < 0) * position.Y = 0; * else if (position.Y >= Surface.SizeY) * position.Y = Surface.SizeY - 1; */ return(position); }
private CentralDerivative(Function function, double step, int order) { if (order < 0) { throw new ArgumentOutOfRangeException("order", "The order of the derivative must be non-negative"); } if (step <= 0) { throw new ArgumentOutOfRangeException("step", "The step of approximation must be positive"); } nStep = Math.Pow(step, order); this.function = function; terms = new Term[order + 1]; for (int i = 0; i <= order; i++) { double coefficient = (i % 2 == 0) ? MathExtra.BinomialCoefficient(order, i) : -MathExtra.BinomialCoefficient(order, i); double translation = (order / 2.0 - i) * step; terms[i] = new Term(coefficient, translation); } }
private void RaiseMountain(int x, int y, int radius, Random rng) { int minX = x - radius; int maxX = x + radius; int minY = Math.Max(y - radius, 0); int maxY = Math.Min(y + radius, SizeY - 1); int radiusSquared = radius * radius; for (int x2 = minX; x2 <= maxX; x2++) { for (int y2 = minY; y2 <= maxY; y2++) { int dx = x2 - x; int dy = y2 - y; int distanceSquared = dx * dx + dy * dy; if (distanceSquared < radiusSquared) { int delta = radiusSquared - distanceSquared; double change = AltitudeScale / 4096 * delta * rng.NextDouble(); Altitude[MathExtra.Wrap(x2, SizeX), y2] += change; } } } }
public static float fastSqrt(float x) { return(1f / MathExtra.InverseSqrtFast(x)); }
public static float GetV3L(Vector3 v) { return(MathExtra.fastSqrt(Mathf.Pow(v.x, 2f) + Mathf.Pow(v.y, 2f) + Mathf.Pow(v.z, 2f))); }