public async Task TeleportAsync(VectorF pos) { this.LastPosition = this.Position; this.Position = pos; await this.client.Server.World.ResendBaseChunksAsync(this.client); var tid = Globals.Random.Next(0, 999); await client.Server.Events.InvokePlayerTeleportedAsync( new PlayerTeleportEventArgs ( this, this.Position, pos )); await this.client.QueuePacketAsync(new ClientPlayerPositionLook { Position = pos, Flags = PositionFlags.None, TeleportId = tid }); this.TeleportId = tid; }
//-------------------------------------------------------------- /// <summary> /// Creates the principal component analysis for the given list of points. /// </summary> /// <param name="points"> /// The list of data points. All points must have the same /// <see cref="VectorF.NumberOfElements"/>. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="points"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="points"/> is empty. /// </exception> public PrincipalComponentAnalysisF(IList<VectorF> points) { if (points == null) throw new ArgumentNullException("points"); if (points.Count == 0) throw new ArgumentException("The list of points is empty."); // Compute covariance matrix. MatrixF covarianceMatrix = StatisticsHelper.ComputeCovarianceMatrix(points); // Perform Eigenvalue decomposition. EigenvalueDecompositionF evd = new EigenvalueDecompositionF(covarianceMatrix); int numberOfElements = evd.RealEigenvalues.NumberOfElements; Variances = new VectorF(numberOfElements); V = new MatrixF(numberOfElements, numberOfElements); // Sort eigenvalues by decreasing value. // Since covarianceMatrix is symmetric, we have no imaginary eigenvalues. for (int i = 0; i < Variances.NumberOfElements; i++) { int index = evd.RealEigenvalues.IndexOfLargestElement; Variances[i] = evd.RealEigenvalues[index]; V.SetColumn(i, evd.V.GetColumn(index)); evd.RealEigenvalues[index] = float.NegativeInfinity; } }
public async virtual Task TeleportAsync(VectorF pos) { if (VectorF.Distance(this.Position, pos) > 8) { await this.server.QueueBroadcastPacketAsync(new EntityTeleport { EntityId = this.EntityId, OnGround = this.OnGround, Position = pos, Pitch = this.Pitch, Yaw = this.Yaw, }); return; } var delta = (Vector)(pos * 32 - Position * 32) * 128; await this.server.QueueBroadcastPacketAsync(new EntityPositionAndRotation { EntityId = this.EntityId, Delta = delta, OnGround = this.OnGround, Pitch = this.Pitch, Yaw = this.Yaw }); }
public void TestRandomRegularA() { RandomHelper.Random = new Random(1); for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(3); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(3); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) { column2[0]++; } // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(3, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); SingularValueDecompositionF svd = new SingularValueDecompositionF(a); Assert.AreEqual(3, svd.NumericalRank); Assert.IsTrue(MatrixF.AreNumericallyEqual(a, svd.U * svd.S * svd.V.Transposed)); Assert.AreEqual(svd.SingularValues[0], svd.Norm2); float condNumber = svd.ConditionNumber; } }
public bool PutInBoard(Shape shape) { foreach (Transform transform in shape.transform) { Vector3 position = VectorF.Round(transform.position); if (position.x < 0) { MoveRight(); if (PutInBoard(shape)) { if (shape.indexShape == 0) { shape.rotateIn9 = false; shape.rotateIn2 = true; } break; } } else if (position.x >= mWidth) { MoveLeft(); if (PutInBoard(shape)) { if (shape.indexShape == 0) { shape.rotateIn2 = false; shape.rotateIn9 = true; } break; } } } return(true); }
public void UpdatePosition(VectorF pos, Angle yaw, Angle pitch, bool onGround = true) { this.Position = pos; this.Yaw = yaw; this.Pitch = pitch; this.OnGround = onGround; }
public void Test6() { MatrixF A = new MatrixF(new float[, ] { { -21, 2, -4, 0 }, { 2, 3, 0.1f, -1 }, { 2, 10, 111.1f, -11 }, { 23, 112, 111.1f, -143 } }); VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f }); SorMethodF solver = new SorMethodF(); solver.MaxNumberOfIterations = 4; VectorF x = solver.Solve(A, null, b); VectorF solution = MatrixF.SolveLinearEquations(A, b); Assert.IsFalse(VectorF.AreNumericallyEqual(solution, x)); Assert.AreEqual(4, solver.NumberOfIterations); // Compare with Gauss-Seidel. Must be equal. GaussSeidelMethodF gsSolver = new GaussSeidelMethodF(); gsSolver.MaxNumberOfIterations = 4; VectorF gsSolution = gsSolver.Solve(A, null, b); Assert.IsTrue(VectorF.AreNumericallyEqual(gsSolution, x)); }
/// <summary>Creates a new instance of NodeDestDistInt.</summary> /// <param name="node">The source Node.</param> /// <param name="dest">The destination of the new node.</param> /// <param name="dist">The distance from the source node to the nearest intersection.</param> /// <param name="intersections">The number of intersections.</param> public NodeDestDistInt(Node node, VectorF dest, FInt dist, int intersections) { this.Node = node; this.Dest = dest; this.Dist = dist; this.Intersections = intersections; }
public void wrong_size_throws() { var a = new VectorF(5); var b = new VectorF(3); Assert.Throws <ArgumentOutOfRangeException>(() => a.GetDistanceSquared(b)); }
/// <summary> /// Computes the new state x1 at time t1. /// </summary> /// <param name="x0">The state x0 at time t0.</param> /// <param name="t0">The time t0.</param> /// <param name="t1">The target time t1 for which the new state x1 is computed.</param> /// <returns>The new state x1 at time t1.</returns> public override VectorF Integrate(VectorF x0, float t0, float t1) { float dt = (t1 - t0); VectorF d = FirstOrderDerivative(x0, t0); VectorF result = x0 + dt * d; return result; }
public async Task TeleportAsync(CommandContext Context, [Remaining] VectorF location) { var player = Context.Player; await player.SendMessageAsync($"ight homie tryna tp you (and sip dicks) {location.X} {location.Y} {location.Z}"); await player.TeleportAsync(location); }
public void Add() { VectorF v1 = new VectorF(new float[] { 1, 2, 3, 4, 5 }); VectorF v2 = new VectorF(new float[] { 6, 7, 8, 9, 10 }); VectorF v3 = VectorF.Add(v1, v2); Assert.AreEqual(new VectorF(new float[] { 7, 9, 11, 13, 15 }), v3); }
public PointF GetVictimNextPoint() { Direction = new VectorF(Victim.Location.X - Location.X, Victim.Location.Y - Location.Y); var nextPoint = new PointF(Location.X + Speed * Direction.X, Location.Y + Speed * Direction.Y); return(nextPoint); }
public void projecting_different_dimensions_throws() { var u = new VectorF(5); var v = new VectorF(3); Assert.Throws <ArgumentOutOfRangeException>(() => u.GetProjected(v)); }
public void subtracting_null_vector_throws() { var left = new VectorF(3); VectorF right = null; Assert.Throws <ArgumentNullException>(() => left.Subtract(right)); }
/// <summary> /// Creates the principal component analysis for the given list of points. /// </summary> /// <param name="points"> /// The list of data points. All points must have the same /// <see cref="VectorF.NumberOfElements"/>. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="points"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="points"/> is empty. /// </exception> public PrincipalComponentAnalysisF(IList <VectorF> points) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Count == 0) { throw new ArgumentException("The list of points is empty."); } // Compute covariance matrix. MatrixF covarianceMatrix = StatisticsHelper.ComputeCovarianceMatrix(points); // Perform Eigenvalue decomposition. EigenvalueDecompositionF evd = new EigenvalueDecompositionF(covarianceMatrix); int numberOfElements = evd.RealEigenvalues.NumberOfElements; Variances = new VectorF(numberOfElements); V = new MatrixF(numberOfElements, numberOfElements); // Sort eigenvalues by decreasing value. // Since covarianceMatrix is symmetric, we have no imaginary eigenvalues. for (int i = 0; i < Variances.NumberOfElements; i++) { int index = evd.RealEigenvalues.IndexOfLargestElement; Variances[i] = evd.RealEigenvalues[index]; V.SetColumn(i, evd.V.GetColumn(index)); evd.RealEigenvalues[index] = float.NegativeInfinity; } }
public void different_sizes_throws() { var left = new VectorF(5); var right = new VectorF(3); Assert.Throws <ArgumentOutOfRangeException>(() => left.GetDot(right)); }
void Start() { m_gameBoard = GameObject.FindWithTag("Board").GetComponent <Board>(); m_spawner = GameObject.FindWithTag("Spawner").GetComponent <Spawner>(); m_score = GameObject.FindObjectOfType <ScoreScript>(); if (m_spawner) { m_spawner.transform.position = VectorF.Round(m_spawner.transform.position); if (!m_activeShape) { m_activeShape = m_spawner.SpawnShape(); } } if (m_gameOverPanel) { m_gameOverPanel.SetActive(false); } if (m_pausePanel) { m_pausePanel.SetActive(false); } }
public void adding_null_vector_throws() { var left = new VectorF(3); VectorF right = null; Assert.Throws <ArgumentNullException>(() => left.GetSum(right)); }
public void TestWarmStarting() { MatrixF A = new MatrixF(new float[, ] { { -21, 2, -4, 0 }, { 2, 3, 0.1f, -1 }, { 2, 10, 111.1f, -11 }, { 23, 112, 111.1f, -143 } }); VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f }); SorMethodF solver = new SorMethodF(); VectorF x = solver.Solve(A, null, b); int fullIterationCount = solver.NumberOfIterations; VectorF solution = MatrixF.SolveLinearEquations(A, b); Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x)); // Now test make separate solve calls with warm-starting solver.MaxNumberOfIterations = 3; x = solver.Solve(A, null, b); Assert.AreEqual(3, solver.NumberOfIterations); solver.MaxNumberOfIterations = 100; x = solver.Solve(A, x, b); Assert.AreEqual(fullIterationCount, solver.NumberOfIterations + 3); }
public async Task TeleportAsync(CommandContext Context, [Remaining] VectorF location) { var player = Context.Player; await player.SendMessageAsync($"Teleporting to {location.X} {location.Y} {location.Z}"); await player.TeleportAsync(location); }
internal virtual async Task UpdateAsync(Server server, VectorF position, bool onGround) { var newPos = position * 32 * 64; var lastPos = this.LastPosition * 32 * 64; short newX = (short)(newPos.X - lastPos.X); short newY = (short)(newPos.Y - lastPos.Y); short newZ = (short)(newPos.Z - lastPos.Z); var isNewLocation = position != this.LastPosition; if (isNewLocation) { server.BroadcastPacketWithoutQueue(new EntityPosition { EntityId = this.EntityId, DeltaX = newX, DeltaY = newY, DeltaZ = newZ, OnGround = onGround }, this.EntityId); this.UpdatePosition(position, onGround); } await Task.CompletedTask; }
// Draws y(t). yOffset is used to position the graph on the screen. private void PlotGraph(OdeIntegratorF integrator, float yOffset, string text) { var debugRenderer = GraphicsScreen.DebugRenderer2D; debugRenderer.DrawText(text, new Vector2F(400, yOffset - 90), Color.Black); debugRenderer.DrawLine( new Vector3F(90, yOffset, 0), new Vector3F(700, yOffset, 0), Color.Black, true); debugRenderer.DrawLine( new Vector3F(100, yOffset - 110, 0), new Vector3F(100, yOffset + 10, 0), Color.Black, true); // In the general case y can be a vector. In this example, y is one-dimensional. // We start with y(0) = 100. VectorF y = new VectorF(new float[1] { 100 }); float lastY = y[0]; // Plot the graph from t = 0 to t = 1. for (float time = 0; time < 1; time += _deltaTime) { // Given y(time), compute y(time + deltaTime). y = integrator.Integrate(y, time, time + _deltaTime); debugRenderer.DrawLine( new Vector3F(100 + time * 600, yOffset - lastY, 0), new Vector3F(100 + (time + _deltaTime) * 600, yOffset - y[0], 0), Color.Black, true); lastY = y[0]; } }
public void Test() { // Make a random list. RandomHelper.Random = new Random(77); List <VectorF> points = new List <VectorF>(); for (int i = 0; i < 10; i++) { var vector = new VectorF(4); RandomHelper.Random.NextVectorF(vector, -1, 10); points.Add(vector); } PrincipalComponentAnalysisF pca = new PrincipalComponentAnalysisF(points); Assert.Greater(pca.Variances[0], pca.Variances[1]); Assert.Greater(pca.Variances[1], pca.Variances[2]); Assert.Greater(pca.Variances[2], pca.Variances[3]); Assert.Greater(pca.Variances[3], 0); Assert.IsTrue(pca.V.GetColumn(0).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(1).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(2).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(3).IsNumericallyNormalized); // Compute covariance matrix and check if it is diagonal in the transformed space. MatrixF cov = StatisticsHelper.ComputeCovarianceMatrix(points); MatrixF transformedCov = pca.V.Transposed * cov * pca.V; for (int row = 0; row < transformedCov.NumberOfRows; row++) { for (int column = 0; column < transformedCov.NumberOfColumns; column++) { if (row != column) { Assert.IsTrue(Numeric.IsZero(transformedCov[row, column])); } } } // The principal components must be Eigenvectors which means that multiplying with the covariance // matrix does only change the length! VectorF v0 = pca.V.GetColumn(0); VectorF v0Result = cov * v0; Assert.IsTrue(VectorF.AreNumericallyEqual(v0.Normalized, v0Result.Normalized)); VectorF v1 = pca.V.GetColumn(1); VectorF v1Result = cov * v1; Assert.IsTrue(VectorF.AreNumericallyEqual(v1.Normalized, v1Result.Normalized)); VectorF v2 = pca.V.GetColumn(2); VectorF v2Result = cov * v2; Assert.IsTrue(VectorF.AreNumericallyEqual(v2.Normalized, v2Result.Normalized)); VectorF v3 = pca.V.GetColumn(3); VectorF v3Result = cov * v3; Assert.IsTrue(VectorF.AreNumericallyEqual(v3.Normalized, v3Result.Normalized)); }
/// <summary> /// Creates the eigenvalue decomposition of the given matrix. /// </summary> /// <param name="matrixA">The square matrix A.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixA"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrixA"/> is non-square (rectangular). /// </exception> public EigenvalueDecompositionF(MatrixF matrixA) { if (matrixA == null) { throw new ArgumentNullException("matrixA"); } if (matrixA.IsSquare == false) { throw new ArgumentException("The matrix A must be square.", "matrixA"); } _n = matrixA.NumberOfColumns; _d = new VectorF(_n); _e = new VectorF(_n); _isSymmetric = matrixA.IsSymmetric; if (_isSymmetric) { _v = matrixA.Clone(); // Tridiagonalize. ReduceToTridiagonal(); // Diagonalize. TridiagonalToQL(); } else { _v = new MatrixF(_n, _n); // Abort if A contains NaN values. // If we continue with NaN values, we run into an infinite loop. for (int i = 0; i < _n; i++) { for (int j = 0; j < _n; j++) { if (Numeric.IsNaN(matrixA[i, j])) { _e.Set(float.NaN); _v.Set(float.NaN); _d.Set(float.NaN); return; } } } // Storage of nonsymmetric Hessenberg form. MatrixF matrixH = matrixA.Clone(); // Working storage for nonsymmetric algorithm. float[] ort = new float[_n]; // Reduce to Hessenberg form. ReduceToHessenberg(matrixH, ort); // Reduce Hessenberg to real Schur form. HessenbergToRealSchur(matrixH); } }
public void TestRandomSpdA() { RandomHelper.Random = new Random(1); // Every transpose(A) * A is SPD if A has full column rank and m>n. for (int i = 0; i < 100; i++) { VectorF column1 = new VectorF(4); RandomHelper.Random.NextVectorF(column1, 1, 2); VectorF column2 = new VectorF(4); RandomHelper.Random.NextVectorF(column2, 1, 2); // Make linearly independent. if (column1 / column1[0] == column2 / column2[0]) { column2[0]++; } // Create linearly independent third column. VectorF column3 = column1 + column2; column3[1]++; // Create A. MatrixF a = new MatrixF(4, 3); a.SetColumn(0, column1); a.SetColumn(1, column2); a.SetColumn(2, column3); MatrixF spdMatrix = a.Transposed * a; CholeskyDecompositionF d = new CholeskyDecompositionF(spdMatrix); Assert.AreEqual(true, d.IsSymmetricPositiveDefinite); MatrixF l = d.L; // Test if L is a lower triangular matrix. for (int j = 0; j < l.NumberOfRows; j++) { for (int k = 0; k < l.NumberOfColumns; k++) { if (j < k) { Assert.AreEqual(0, l[j, k]); } } } Assert.IsTrue(MatrixF.AreNumericallyEqual(spdMatrix, l * l.Transposed)); // Check solving of linear equations. MatrixF b = new MatrixF(3, 2); RandomHelper.Random.NextMatrixF(b, 0, 1); MatrixF x = d.SolveLinearEquations(b); MatrixF b2 = spdMatrix * x; Assert.IsTrue(MatrixF.AreNumericallyEqual(b, b2, 0.01f)); } }
public void can_get_componenets() { var v = new VectorF(new[] { 3.0f, 4.0f, 5.0f }); Assert.Equal(3.0, v[0]); Assert.Equal(4.0, v[1]); Assert.Equal(5.0, v[2]); }
public void copy_constructor_copies_componenets_from_ivector() { var expected = new VectorF(new[] { 1.0f, 2.0f, 3.3f, 4.4f }); var actual = new VectorF((IVector <float>)expected); Assert.Equal(expected, actual); }
public virtual bool setOrbitObject(GameBase orbitObject, VectorF rotation, float minDistance, float maxDistance, float initDistance, bool ownClientObject = false, Point3F offset = null, bool locked = false) { if (offset == null) { offset = Point3F.Zero; } return(InternalUnsafeMethods.setOrbitObject(ObjectPtr, orbitObject.ObjectPtr, rotation.ToStruct(), minDistance, maxDistance, initDistance, ownClientObject, offset.ToStruct(), locked)); }
public virtual void setForwardVector(VectorF newForward = null) { if (newForward == null) { newForward = new VectorF(0, 0, 0); } InternalUnsafeMethods.setForwardVector(ObjectPtr, newForward.ToStruct()); }
public void StoreShapeInGrid(Shape shape) { foreach (Transform chield in shape.transform) { Vector3 position = VectorF.Round(chield.transform.position); m_grid[(int)position.x, (int)position.y] = chield; } }
public void Test1() { VectorF state = new VectorF(new float[] { 0, 1 }); VectorF result = new RungeKutta4IntegratorF(GetFirstOrderDerivatives).Integrate(state, 2, 2.5f); Assert.AreEqual(0f, result[0]); Assert.AreEqual(3.061035156f, result[1]); }
public void Test1() { VectorF state = new VectorF(new float[]{ 0, 1 }); VectorF result = new RungeKutta4IntegratorF(GetFirstOrderDerivatives).Integrate(state, 2, 2.5f); Assert.AreEqual(0f, result[0]); Assert.AreEqual(3.061035156f, result[1]); }
public void Reset() { InitialVelocity = new VectorF(0, 0); InitialAngularVelocity = 0; InitialExpansionVelocity = 0; _stopwatch.Reset(); _stopwatch.Start(); }
public static bool IsObjectAt(float ptX, float ptY, TransformParams tr, float x1, float y1, float x2, float y2, ref float dist) { Utils.ThrowException(tr.NotSet ? new ArgumentValueException("tr") : null); VectorF pt1 = tr.Transform(new VectorF(x1, y1)); VectorF pt2 = tr.Transform(new VectorF(x2, y2)); return(VisualizationUtils.TestLineHit(new VectorF(ptX, ptY), pt1, pt2, mHitDist, ref dist)); }
public void can_get_componenets() { var v = new VectorF(new[] { 3.0f, 4.0f, 5.0f }); Assert.Equal(3.0, v.Get(0)); Assert.Equal(4.0, v.Get(1)); Assert.Equal(5.0, v.Get(2)); }
public VectorF GetFirstOrderDerivatives(VectorF x, float t) { // A dummy function: f(x[index], t) = index * t; VectorF result = new VectorF(x.NumberOfElements); for (int i = 0; i < result.NumberOfElements; i++) result[i] = i*t; return result; }
//-------------------------------------------------------------- /// <summary> /// Creates the eigenvalue decomposition of the given matrix. /// </summary> /// <param name="matrixA">The square matrix A.</param> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixA"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrixA"/> is non-square (rectangular). /// </exception> public EigenvalueDecompositionF(MatrixF matrixA) { if (matrixA == null) throw new ArgumentNullException("matrixA"); if (matrixA.IsSquare == false) throw new ArgumentException("The matrix A must be square.", "matrixA"); _n = matrixA.NumberOfColumns; _d = new VectorF(_n); _e = new VectorF(_n); _isSymmetric = matrixA.IsSymmetric; if (_isSymmetric) { _v = matrixA.Clone(); // Tridiagonalize. ReduceToTridiagonal(); // Diagonalize. TridiagonalToQL(); } else { _v = new MatrixF(_n, _n); // Abort if A contains NaN values. // If we continue with NaN values, we run into an infinite loop. for (int i = 0; i < _n; i++) { for (int j = 0; j < _n; j++) { if (Numeric.IsNaN(matrixA[i, j])) { _e.Set(float.NaN); _v.Set(float.NaN); _d.Set(float.NaN); return; } } } // Storage of nonsymmetric Hessenberg form. MatrixF matrixH = matrixA.Clone(); // Working storage for nonsymmetric algorithm. float[] ort = new float[_n]; // Reduce to Hessenberg form. ReduceToHessenberg(matrixH, ort); // Reduce Hessenberg to real Schur form. HessenbergToRealSchur(matrixH); } }
public void SolveWithDefaultInitialGuess() { MatrixF A = new MatrixF(new float[,] { { 4 } }); VectorF b = new VectorF(new float[] { 20 }); JacobiMethodF solver = new JacobiMethodF(); VectorF x = solver.Solve(A, b); Assert.IsTrue(VectorF.AreNumericallyEqual(new VectorF(1, 5), x)); Assert.AreEqual(2, solver.NumberOfIterations); }
public void Test1() { MatrixF A = new MatrixF(new float[,] { { 4 } }); VectorF b = new VectorF(new float[] { 20 }); SorMethodF solver = new SorMethodF(); VectorF x = solver.Solve(A, null, b); Assert.IsTrue(VectorF.AreNumericallyEqual(new VectorF(1, 5), x)); Assert.AreEqual(2, solver.NumberOfIterations); }
public void Test1() { VectorF state = new VectorF (new float[] { 0, 1, 2, 3, 4, 5 }); VectorF result = new MidpointIntegratorF(GetFirstOrderDerivatives).Integrate(state, 2, 2.5f); Assert.AreEqual(0f, result[0]); Assert.AreEqual(2.125f, result[1]); Assert.AreEqual(4.25f, result[2]); Assert.AreEqual(6.375f, result[3]); Assert.AreEqual(8.5f, result[4]); Assert.AreEqual(10.625f, result[5]); }
public void Test4() { MatrixF A = new MatrixF(new float[,] { { -12, 2 }, { 2, 3 }}); VectorF b = new VectorF(new float[] { 20, 28 }); SorMethodF solver = new SorMethodF(); VectorF x = solver.Solve(A, null, b); VectorF solution = MatrixF.SolveLinearEquations(A, b); Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x)); }
public void Test2() { MatrixF A = new MatrixF(new float[,] { { 1, 0 }, { 0, 1 }}); VectorF b = new VectorF(new float[] { 20, 28 }); JacobiMethodF solver = new JacobiMethodF(); VectorF x = solver.Solve(A, null, b); Assert.IsTrue(VectorF.AreNumericallyEqual(b, x)); Assert.AreEqual(2, solver.NumberOfIterations); }
public void Test1() { VectorF state = new VectorF (new float[]{ 1, 2, 3, 4, 5, 6 }); VectorF result = new ExplicitEulerIntegratorF(GetFirstOrderDerivatives).Integrate(state, 2, 2.5f); Assert.AreEqual(1f, result[0]); Assert.AreEqual(3f, result[1]); Assert.AreEqual(5f, result[2]); Assert.AreEqual(7f, result[3]); Assert.AreEqual(9f, result[4]); Assert.AreEqual(11f, result[5]); }
public void Test3() { MatrixF A = new MatrixF(new float[,] { { 2, 0 }, { 0, 2 }}); VectorF b = new VectorF(new float[] { 20, 28 }); GaussSeidelMethodF solver = new GaussSeidelMethodF(); VectorF x = solver.Solve(A, null, b); Assert.IsTrue(VectorF.AreNumericallyEqual(b / 2, x)); Assert.AreEqual(2, solver.NumberOfIterations); }
public void Test5() { MatrixF A = new MatrixF(new float[,] { { -21, 2, -4, 0 }, { 2, 3, 0.1f, -1 }, { 2, 10, 111.1f, -11 }, { 23, 112, 111.1f, -143 }}); VectorF b = new VectorF(new float[] { 20, 28, -12, 0.1f }); GaussSeidelMethodF solver = new GaussSeidelMethodF(); VectorF x = solver.Solve(A, null, b); VectorF solution = MatrixF.SolveLinearEquations(A, b); Assert.IsTrue(VectorF.AreNumericallyEqual(solution, x)); }
public void Test() { // Make a random list. RandomHelper.Random = new Random(77); List<VectorF> points = new List<VectorF>(); for (int i = 0; i < 10; i++) { var vector = new VectorF(4); RandomHelper.Random.NextVectorF(vector, -1, 10); points.Add(vector); } PrincipalComponentAnalysisF pca = new PrincipalComponentAnalysisF(points); Assert.Greater(pca.Variances[0], pca.Variances[1]); Assert.Greater(pca.Variances[1], pca.Variances[2]); Assert.Greater(pca.Variances[2], pca.Variances[3]); Assert.Greater(pca.Variances[3], 0); Assert.IsTrue(pca.V.GetColumn(0).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(1).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(2).IsNumericallyNormalized); Assert.IsTrue(pca.V.GetColumn(3).IsNumericallyNormalized); // Compute covariance matrix and check if it is diagonal in the transformed space. MatrixF cov = StatisticsHelper.ComputeCovarianceMatrix(points); MatrixF transformedCov = pca.V.Transposed * cov * pca.V; for (int row = 0; row < transformedCov.NumberOfRows; row++) for (int column = 0; column < transformedCov.NumberOfColumns; column++) if (row != column) Assert.IsTrue(Numeric.IsZero(transformedCov[row, column])); // The principal components must be Eigenvectors which means that multiplying with the covariance // matrix does only change the length! VectorF v0 = pca.V.GetColumn(0); VectorF v0Result = cov * v0; Assert.IsTrue(VectorF.AreNumericallyEqual(v0.Normalized, v0Result.Normalized)); VectorF v1 = pca.V.GetColumn(1); VectorF v1Result = cov * v1; Assert.IsTrue(VectorF.AreNumericallyEqual(v1.Normalized, v1Result.Normalized)); VectorF v2 = pca.V.GetColumn(2); VectorF v2Result = cov * v2; Assert.IsTrue(VectorF.AreNumericallyEqual(v2.Normalized, v2Result.Normalized)); VectorF v3 = pca.V.GetColumn(3); VectorF v3Result = cov * v3; Assert.IsTrue(VectorF.AreNumericallyEqual(v3.Normalized, v3Result.Normalized)); }
public void Absolute() { VectorF v = new VectorF(new float[] { -1, -2, -3, -4 }); v.Absolute(); Assert.AreEqual(1, v[0]); Assert.AreEqual(2, v[1]); Assert.AreEqual(3, v[2]); Assert.AreEqual(4, v[3]); v = new VectorF(new float[] { 1, 2, 3, 4 }); v.Absolute(); Assert.AreEqual(1, v[0]); Assert.AreEqual(2, v[1]); Assert.AreEqual(3, v[2]); Assert.AreEqual(4, v[3]); }
/// <summary> /// Solves the specified linear system of equations <i>Ax=b</i>. /// </summary> /// <param name="matrixA">The matrix A.</param> /// <param name="initialX"> /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used /// as initial guess. /// </param> /// <param name="vectorB">The vector b.</param> /// <returns>The solution vector x.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixA"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="vectorB"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrixA"/> is not a square matrix. /// </exception> /// <exception cref="ArgumentException"> /// The number of elements of <paramref name="initialX"/> does not match. /// </exception> public override VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB) { // TODO: We can possible improve the method by reordering after each step. // This can be done randomly or we sort by the "convergence" of the elements. // See book Physics-Based Animation. NumberOfIterations = 0; if (matrixA == null) throw new ArgumentNullException("matrixA"); if (vectorB == null) throw new ArgumentNullException("vectorB"); if (matrixA.IsSquare == false) throw new ArgumentException("Matrix A must be a square matrix.", "matrixA"); if (matrixA.NumberOfRows != vectorB.NumberOfElements) throw new ArgumentException("The number of rows of A and b do not match."); if (initialX != null && initialX.NumberOfElements != vectorB.NumberOfElements) throw new ArgumentException("The number of elements of the initial guess for x and b do not match."); VectorF xOld = initialX ?? new VectorF(vectorB.NumberOfElements); VectorF xNew = new VectorF(vectorB.NumberOfElements); bool isConverged = false; // Make iterations until max iteration count or the result has converged. for (int i = 0; i < MaxNumberOfIterations && !isConverged; i++) { for (int j = 0; j < vectorB.NumberOfElements; j++) { float delta = 0; for (int k = 0; k < j; k++) delta += matrixA[j, k] * xOld[k]; for (int k = j + 1; k < vectorB.NumberOfElements; k++) delta += matrixA[j, k] * xOld[k]; xNew[j] = (vectorB[j] - delta) / matrixA[j, j]; } // Test convergence isConverged = VectorF.AreNumericallyEqual(xOld, xNew, Epsilon); xOld = xNew.Clone(); NumberOfIterations = i + 1; } return xNew; }
/// <summary> /// Computes the new state x1 at time t1. /// </summary> /// <param name="x0">The state x0 at time t0.</param> /// <param name="t0">The time t0.</param> /// <param name="t1">The target time t1 for which the new state x1 is computed.</param> /// <returns>The new state x1 at time t1.</returns> public override VectorF Integrate(VectorF x0, float t0, float t1) { float dt = (t1 - t0); VectorF d1 = FirstOrderDerivative(x0, t0); VectorF tmp = x0 + dt / 2 * d1; VectorF d2 = FirstOrderDerivative(tmp, t0 + dt / 2); tmp = x0 + dt / 2 * d2; VectorF d3 = FirstOrderDerivative(tmp, t0 + dt / 2); tmp = x0 + dt * d3; VectorF d4 = FirstOrderDerivative(tmp, t1); VectorF result = x0 + dt / 6 * d1 + dt / 3 * d2 + dt / 3 * d3 + dt / 6 * d4; return result; }
/// <summary>Creates a new instance of FogOfWar.</summary> /// <param name="rows">The number of rows.</param> /// <param name="cols">The number of columns.</param> /// <param name="worldSize">The size of the world.</param> /// <param name="owner">The player that owns this fog of war.</param> public FogOfWar(int rows, int cols, VectorF worldSize, Player owner) { clear(); Owner = owner; Grid = new VisOption[rows, cols]; // set grid square size SqrSize = new VectorF(worldSize.X / (FInt)cols, worldSize.Y / (FInt)rows); SqrSizeHalf = SqrSize / FInt.F2; // begin unexplored resetTo(VisOption.Unexplored); // only use drawn if human drawn = (owner.Type == Player.PlayerType.Human) ? new bool[rows, cols] : null; }
public void AbsoluteStatic() { VectorF v = new VectorF(new float[] { -1, -2, -3, -4 }); VectorF absoluteV = VectorF.Absolute(v); Assert.AreEqual(1, absoluteV[0]); Assert.AreEqual(2, absoluteV[1]); Assert.AreEqual(3, absoluteV[2]); Assert.AreEqual(4, absoluteV[3]); v = new VectorF(new float[] { 1, 2, 3, 4 }); absoluteV = VectorF.Absolute(v); Assert.AreEqual(1, absoluteV[0]); Assert.AreEqual(2, absoluteV[1]); Assert.AreEqual(3, absoluteV[2]); Assert.AreEqual(4, absoluteV[3]); Assert.IsNull(VectorF.Absolute(null)); }
/// <summary> /// Called when <see cref="ScatteredInterpolationF.Compute"/> is called. /// </summary> /// <param name="x">The x value.</param> /// <returns>The y value.</returns> /// <remarks> /// When this method is called, <see cref="ScatteredInterpolationF.Setup"/> has already been /// executed. And the parameter <paramref name="x"/> is not <see langword="null"/>. /// </remarks> protected override VectorF OnCompute(VectorF x) { // Compute weights. float weightSum = 0; int numberOfPairs = Count; for (int i = 0; i < numberOfPairs; i++) { _weights[i] = (float) Math.Pow((x - GetX(i)).Length + Numeric.EpsilonF, -Power); weightSum += _weights[i]; } // Compute result as weighted sum. VectorF y = new VectorF(GetY(0).NumberOfElements); for (int i = 0; i < numberOfPairs; i++) y += _weights[i] * GetY(i); return y / weightSum; }
/// <summary> /// Solves the specified linear system of equations <i>Ax=b</i>. /// </summary> /// <param name="matrixA">The matrix A.</param> /// <param name="initialX"> /// The initial guess for x. If this value is <see langword="null"/>, a zero vector will be used /// as initial guess. /// </param> /// <param name="vectorB">The vector b.</param> /// <returns>The solution vector x.</returns> /// <exception cref="ArgumentNullException"> /// <paramref name="matrixA"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentNullException"> /// <paramref name="vectorB"/> is <see langword="null"/>. /// </exception> /// <exception cref="ArgumentException"> /// <paramref name="matrixA"/> is not a square matrix. /// </exception> /// <exception cref="ArgumentException"> /// The number of elements of <paramref name="initialX"/> does not match. /// </exception> public override VectorF Solve(MatrixF matrixA, VectorF initialX, VectorF vectorB) { NumberOfIterations = 0; if (matrixA == null) throw new ArgumentNullException("matrixA"); if (vectorB == null) throw new ArgumentNullException("vectorB"); if (matrixA.IsSquare == false) throw new ArgumentException("Matrix A must be a square matrix.", "matrixA"); if (matrixA.NumberOfRows != vectorB.NumberOfElements) throw new ArgumentException("The number of rows of A and b do not match."); if (initialX != null && initialX.NumberOfElements != vectorB.NumberOfElements) throw new ArgumentException("The number of elements of the initial guess for x and b do not match."); VectorF xOld = initialX ?? new VectorF(vectorB.NumberOfElements); VectorF xNew = new VectorF(vectorB.NumberOfElements); bool isConverged = false; // Make iterations until max iteration count or the result has converged. for (int i = 0; i < MaxNumberOfIterations && !isConverged; i++) { for (int j=0; j<vectorB.NumberOfElements; j++) { float delta = 0; for (int k=0; k < j; k++) delta += matrixA[j, k] * xNew[k]; for (int k=j+1; k < vectorB.NumberOfElements; k++) delta += matrixA[j, k] * xOld[k]; delta = (vectorB[j] - delta) / matrixA[j, j]; xNew[j] = xOld[j] + RelaxationFactor * (delta - xOld[j]); } // Test convergence isConverged = VectorF.AreNumericallyEqual(xOld, xNew, Epsilon); xOld = xNew.Clone(); NumberOfIterations = i + 1; } return xNew; }
/// <summary>Searches for a collision between the provided node and any node, segment, or geo. Ignores collisions with the specified segments and nodes.</summary> /// <param name="center">The center of the node.</param> /// <param name="radius">The radius of the node.</param> /// <param name="ignoreSeg">The segments to ignore.</param> /// <param name="ignoreNode">The nodes to ignore.</param> /// <param name="includeUnbuilt">Whether or not to test against unfinished nodes or segments owned by a certain player.</param> /// <param name="owner">The owner of the unbuilt nodes and segments to test against.</param> /// <returns>Whether or not there was a collision.</returns> public bool nodeCollision(VectorF center, FInt radius, List<SegmentSkel> ignoreSeg, List<NodeSkel> ignoreNode, bool includeUnbuilt, Player owner) { List<SegmentSkel> segColls = new List<SegmentSkel>(1); List<NodeSkel> nodeColls = new List<NodeSkel>(1); List<GeoSkel> geoColls = new List<GeoSkel>(1); object[] array = new object[7]; array[0] = center; array[1] = radius; array[4] = CollSrchType.DoesItCollide; array[5] = includeUnbuilt; array[6] = owner; // first look for collisions with nodes array[2] = ignoreNode; array[3] = nodeColls; Grid.PointExpand(center, array, gridNodeCollNode); if (nodeColls.Count == 0) { // next look for collisions with segments array[2] = ignoreSeg; array[3] = segColls; Grid.PointExpand(center, array, gridNodeCollSeg); if (segColls.Count == 0) { // next look for collisions with geos array[2] = null; array[3] = geoColls; Grid.PointExpand(center, array, gridNodeCollGeo); } } return nodeColls.Count > 0 || segColls.Count > 0 || geoColls.Count > 0; }
/// <summary>Updates all variables in this mode.</summary> /// <param name="gameTime">The current game time.</param> public override void Update(GameTime gameTime) { base.Update(gameTime); FInt elapsed = (FInt)gameTime.ElapsedGameTime.TotalSeconds; // update gui if (Inp.OldMse.Position != Inp.Mse.Position) desktop.mouseMove(Inp.Mse.Position); GUI.Desktop.Event evnt = Desktop.Event.MouseRightUp; bool guiOwnedInput = false; if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released) guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseLeftUp, Inp.Mse.Position, Inp); if (Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed) guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseLeftDown, Inp.Mse.Position, Inp); if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released) guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseRightUp, Inp.Mse.Position, Inp); if (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed) guiOwnedInput |= desktop.PerformMouseEvent(Desktop.Event.MouseRightUp, Inp.Mse.Position, Inp); Keys[] newKeys = Inp.Key.GetPressedKeys(); if (newKeys.Length != 0) guiOwnedInput |= desktop.PerformKeyEvent(newKeys, Inp); if (guiOwnedInput) { hoveredNode = null; hoveredSeg = null; hoveredSegEnd = null; hoveredSegEndOwner = null; hoveredGeo = null; hoveredHotspot = null; isDragging = false; } else { // prepare grid manager world.Grid.startNewUpdate(gameTime); // move camera if (Inp.Key.IsKeyDown(Keys.OemPlus)) world.Cam.Zoom += world.Cam.Zoom * elapsed; if (Inp.Key.IsKeyDown(Keys.OemMinus)) world.Cam.Zoom -= world.Cam.Zoom * elapsed; if (Inp.Key.IsKeyDown(Keys.A)) world.Cam.CenterX -= (700 / world.Cam.Zoom) * elapsed; if (Inp.Key.IsKeyDown(Keys.D)) world.Cam.CenterX += (700 / world.Cam.Zoom) * elapsed; if (Inp.Key.IsKeyDown(Keys.W)) world.Cam.CenterY -= (700 / world.Cam.Zoom) * elapsed; if (Inp.Key.IsKeyDown(Keys.S)) world.Cam.CenterY += (700 / world.Cam.Zoom) * elapsed; world.Cam.Zoom += (FInt)(Inp.Mse.ScrollWheelValue - Inp.OldMse.ScrollWheelValue) / (FInt)120 * (FInt).1d * world.Cam.Zoom; world.Cam.refreshCorners(); // get cursor world coordinates VectorF cursorPos = world.Cam.screenToWorld(new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y)); // check for hovered node, segment, segment end, and hotspot hoveredNode = world.NodeAtPoint(cursorPos, false); hoveredSeg = (hoveredNode == null) ? world.segmentAtPoint(cursorPos, null) : null; hoveredSegEnd = world.SegmentEndAtPoint(cursorPos); if (hoveredSegEnd != null) { foreach (Segment seg in world.Segments) { if (seg.Nodes[0] == hoveredSegEnd || seg.Nodes[1] == hoveredSegEnd) { hoveredSegEndOwner = seg.Owner; break; } } } else { hoveredSegEndOwner = null; } hoveredHotspot = world.HotspotAtPoint(cursorPos); // test geo vertices hoveredGeo = world.geoAtPoint(cursorPos, out hoveredGeoVertex, true); // test geo lines if (hoveredGeo == null) { hoveredGeo = world.geoAtPoint(cursorPos, out hoveredGeoVertex, false); hoveredGeoIsLine = true; } else { hoveredGeoIsLine = false; } // if the user just released the left mouse button if (Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Released) { if (selectedSegEnd != null) { // do nothing } // add node else if (btnAddNode.Pressed && cmbNodeTypes.SelectedIndex != -1 && selectedGeo == null && (selectedNode == null || isDragging) && selectedSeg == null && selectedHotspot == null) { bool useHoveredEnd = (hoveredSegEnd != null && (selectedNode == null || selectedNode.Owner == hoveredSegEndOwner)); // add node Node node = new Node(world, world.NodeTypes[cmbEditorAddNodeType.SelectedIndex]); node.Pos = useHoveredEnd ? hoveredSegEnd.Pos : cursorPos; node.Active = true; if (selectedNode != null && isDragging) { node.Owner = selectedNode.Owner; if (selectedNode.NumSegments < selectedNode.Segments.Length) // add segment too { Segment seg = new Segment(world); seg.Owner = selectedNode.Owner; seg.Nodes[0] = selectedNode; seg.Nodes[1] = node; selectedNode.addSegment(seg, false); node.addSegment(seg, false); seg.refreshMath(); seg.EndLength[0] = seg.Length; seg.EndLength[1] = seg.Length; seg.refreshEndLocs(); world.addSegment(seg); } } else if (selectedNode == null && hoveredSegEnd != null) { node.Owner = hoveredSegEndOwner; } else if (cmbEditorAddNodeOwner.SelectedIndex != 0) { node.Owner = world.Players[cmbEditorAddNodeOwner.SelectedIndex - 1]; } if (useHoveredEnd) { // link segments to it foreach (Segment seg in (hoveredSegEndOwner == null ? world.Segments : hoveredSegEndOwner.Segments)) { for (int i = 0; i < 2; i++) { if (seg.Nodes[i] == hoveredSegEnd) { seg.Nodes[i] = node; break; } } } } world.addNode(node); selectedNode = node; selectedSeg = null; loadObjectEditor(); } // add segment else if (btnAddSeg.Pressed && isDragging && selectedSeg == null && selectedGeo == null && (selectedNode == null || selectedNode.NumSegments < selectedNode.Segments.Length) && selectedHotspot == null) { Segment seg = new Segment(world); seg.Owner = (selectedNode != null) ? selectedNode.Owner : (hoveredNode != null) ? hoveredNode.Owner : (cmbEditorAddSegOwner.SelectedIndex > 0) ? world.Players[cmbEditorAddSegOwner.SelectedIndex - 1] : null; if (selectedNode != null) { seg.Nodes[0] = selectedNode; seg.Owner = selectedNode.Owner; selectedNode.addSegment(seg, false); } else { seg.State[1] = SegmentSkel.SegState.Retracting; seg.Nodes[0] = new Node(world); seg.Nodes[0].Pos = lastClickedPoint; seg.Nodes[0].Active = false; seg.Nodes[0].Destroyed = true; seg.Nodes[0].initSegArrays(0); } if (hoveredNode != null && hoveredNode.NumSegments != hoveredNode.Segments.Length && (selectedNode == null || (hoveredNode != selectedNode && hoveredNode.Owner == selectedNode.Owner && hoveredNode.relatedSeg(selectedNode) == -1))) { seg.Nodes[1] = hoveredNode; hoveredNode.addSegment(seg, false); } else { seg.State[0] = SegmentSkel.SegState.Building; seg.Nodes[1] = new Node(world); seg.Nodes[1].Pos = cursorPos; seg.Nodes[1].Active = false; seg.Nodes[1].Destroyed = true; seg.Nodes[1].initSegArrays(0); } seg.refreshMath(); seg.EndLength[0] = seg.Length; seg.EndLength[1] = seg.Length; seg.refreshEndLocs(); world.addSegment(seg); selectedNode = null; selectedSeg = seg; loadObjectEditor(); } // add geo vertex else if (btnAddGeo.Pressed && selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedHotspot == null) { // add vertex to existing geo if (selectedGeo != null && !selectedGeoIsLine && isDragging && (selectedGeoVertex == 0 || selectedGeoVertex == selectedGeo.Vertices.Length - 1)) { VectorF[] vertices; if (selectedGeo.Vertices.Length == 1) { vertices = new VectorF[selectedGeo.Vertices.Length + 1]; vertices[0] = cursorPos; vertices[1] = selectedGeo.Vertices[0]; } else if (selectedGeoVertex == 0) { vertices = new VectorF[selectedGeo.Vertices.Length + 2]; selectedGeo.Vertices.CopyTo(vertices, 2); vertices[0] = cursorPos; vertices[1] = selectedGeo.Vertices[0]; } else { vertices = new VectorF[selectedGeo.Vertices.Length + 2]; selectedGeo.Vertices.CopyTo(vertices, 0); vertices[selectedGeo.Vertices.Length] = selectedGeo.Vertices[selectedGeo.Vertices.Length - 1]; vertices[selectedGeo.Vertices.Length + 1] = cursorPos; selectedGeoVertex = vertices.Length - 1; } world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridRemoveGeo); selectedGeo.Vertices = vertices; selectedGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height)); world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridAddGeo); selectedGeoIsLine = false; loadObjectEditor(); } // add vertex in the middle of a line else if (hoveredGeo != null && hoveredGeoIsLine) { VectorF[] vertices = new VectorF[hoveredGeo.Vertices.Length + 2]; int v2 = (hoveredGeoVertex == hoveredGeo.Vertices.Length - 1) ? 0 : hoveredGeoVertex + 1; float dist = (float)Calc.getAdj(VectorF.Distance(cursorPos, hoveredGeo.Vertices[hoveredGeoVertex]), Calc.LinePointDistance(cursorPos, hoveredGeo.Vertices[hoveredGeoVertex], hoveredGeo.Vertices[v2])); Vector2 dir = Vector2.Normalize((Vector2)(hoveredGeo.Vertices[v2] - hoveredGeo.Vertices[hoveredGeoVertex])); VectorF pos = (VectorF)((Vector2)hoveredGeo.Vertices[hoveredGeoVertex] + (dir * dist)); for (int i = 0; i <= hoveredGeoVertex; i++) { vertices[i] = hoveredGeo.Vertices[i]; } if (hoveredGeoVertex == selectedGeo.Vertices.Length - 1) { vertices[hoveredGeoVertex + 1] = selectedGeo.Vertices[selectedGeo.Vertices.Length - 1]; vertices[hoveredGeoVertex + 2] = pos; } else { vertices[hoveredGeoVertex + 1] = pos; vertices[hoveredGeoVertex + 2] = pos; for (int i = hoveredGeoVertex + 1; i < hoveredGeo.Vertices.Length; i++) { vertices[i + 2] = hoveredGeo.Vertices[i]; } } world.Grid.Rect(hoveredGeo.UpperLeft, hoveredGeo.LowerRight, hoveredGeo, world.gridRemoveGeo); hoveredGeo.Vertices = vertices; hoveredGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height)); world.Grid.Rect(hoveredGeo.UpperLeft, hoveredGeo.LowerRight, hoveredGeo, world.gridAddGeo); hoveredGeoIsLine = false; hoveredGeoVertex += 2; selectedGeo = hoveredGeo; selectedGeoIsLine = false; selectedGeoVertex = hoveredGeoVertex; loadObjectEditor(); } // add new geo else if (hoveredGeo == null) { Geo geo = new Geo(world); geo.Vertices = new VectorF[] { cursorPos }; geo.CloseLoop = false; geo.Display = false; geo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height)); world.addGeo(geo); selectedGeo = geo; selectedGeoIsLine = false; selectedGeoVertex = 0; loadObjectEditor(); } } else if (btnAddHotspot.Pressed && selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedGeo == null) { // add hotspot Hotspot hotspot = new Hotspot(world); hotspot.Pos = cursorPos; world.addHotspot(hotspot); selectedHotspot = hotspot; loadObjectEditor(); } selectedSegEnd = null; isDragging = false; } // if the player just released the right mouse button else if (Inp.OldMse.RightButton == ButtonState.Pressed && Inp.Mse.RightButton == ButtonState.Released) { } // user just pressed the left mouse button else if (Inp.OldMse.LeftButton == ButtonState.Released && Inp.Mse.LeftButton == ButtonState.Pressed) { lastClickedPoint = world.Cam.screenToWorld(new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y)); isDragging = false; // check for selected node selectedNode = hoveredNode; // check for selected segment end selectedSegEnd = (selectedNode == null) ? hoveredSegEnd : null; // check for selected segment selectedSeg = (selectedNode == null && selectedSegEnd == null) ? hoveredSeg : null; // check for selected hotspot selectedHotspot = (selectedNode == null && selectedSegEnd == null && selectedSeg == null) ? hoveredHotspot : null; // check for selected geo if (selectedNode == null && selectedSeg == null && selectedSegEnd == null && selectedHotspot == null) { selectedGeo = hoveredGeo; selectedGeoIsLine = hoveredGeoIsLine; selectedGeoVertex = hoveredGeoVertex; } else { selectedGeo = null; } loadObjectEditor(); } // user just pressed the right mouse button else if (Inp.OldMse.RightButton == ButtonState.Released && Inp.Mse.RightButton == ButtonState.Pressed) { } // if the left mouse button is still pressed else if (desktop.Focused == null && Inp.OldMse.LeftButton == ButtonState.Pressed && Inp.Mse.LeftButton == ButtonState.Pressed) { if (!isDragging && Vector2.Distance(world.Cam.worldToScreen(lastClickedPoint), new Vector2((float)Inp.Mse.X, (float)Inp.Mse.Y)) >= distToDrag) { isDragging = true; if (selectedNode != null) dragOffset = selectedNode.Pos - lastClickedPoint; else if (selectedSegEnd != null) dragOffset = selectedSegEnd.Pos - lastClickedPoint; else if (selectedSeg != null) dragOffset = selectedSeg.Nodes[0].Pos - lastClickedPoint; else if (selectedHotspot != null) dragOffset = selectedHotspot.Pos - lastClickedPoint; else if (selectedGeo != null) { if (selectedGeoVertex == -1) dragOffset = selectedGeo.Center - lastClickedPoint; else dragOffset = selectedGeo.Vertices[selectedGeoVertex] - lastClickedPoint; } } } // if [Del] key is pressed else if (!Inp.OldKey.IsKeyDown(Keys.Delete) && Inp.Key.IsKeyDown(Keys.Delete)) { if (selectedNode != null) removeSelNode(); else if (selectedSeg != null) removeSelSeg(); else if (selectedHotspot != null) removeSelHotspot(); else if (selectedGeo != null) removeSelGeo(); } // drag if (isDragging) { // move node if (selectedNode != null && !btnAddSeg.Pressed && (!btnAddNode.Pressed || cmbEditorAddNodeType.SelectedIndex < 0)) { moveNode(selectedNode, cursorPos + dragOffset); } // move segment end else if (selectedSegEnd != null) { moveNode(selectedSegEnd, cursorPos + dragOffset); } // move segment else if (selectedSeg != null) { VectorF moveVect = cursorPos + dragOffset - selectedSeg.Nodes[0].Pos; moveNode(selectedSeg.Nodes[0], selectedSeg.Nodes[0].Pos + moveVect); moveNode(selectedSeg.Nodes[1], selectedSeg.Nodes[1].Pos + moveVect); } // move hotspot else if (selectedHotspot != null) { moveHotspot(selectedHotspot, cursorPos + dragOffset); } // move geo/vertex else if (selectedGeo != null && !btnAddGeo.Pressed) { world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridRemoveGeo); if (selectedGeoIsLine) { if (selectedGeoVertex == selectedGeo.Vertices.Length - 1) { selectedGeo.Vertices[0] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex]; } else { if (selectedGeoVertex != 0) selectedGeo.Vertices[selectedGeoVertex - 1] = cursorPos + dragOffset; selectedGeo.Vertices[selectedGeoVertex + 1] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex]; if (selectedGeoVertex != selectedGeo.Vertices.Length - 2) selectedGeo.Vertices[selectedGeoVertex + 2] += cursorPos + dragOffset - selectedGeo.Vertices[selectedGeoVertex]; } selectedGeo.Vertices[selectedGeoVertex] = cursorPos + dragOffset; } else if (selectedGeoVertex == -1) { VectorF toMove = cursorPos + dragOffset - selectedGeo.Center; for (int i = 0; i < selectedGeo.Vertices.Length; i++) { selectedGeo.Vertices[i] += toMove; } } else { if (selectedGeoVertex != 0 && selectedGeoVertex != selectedGeo.Vertices.Length - 1) selectedGeo.Vertices[selectedGeoVertex - 1] = cursorPos + dragOffset; selectedGeo.Vertices[selectedGeoVertex] = cursorPos + dragOffset; } selectedGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height)); world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridAddGeo); } } } }
/// <summary>Removes the selected geo vertex or line from the world.</summary> private void removeSelGeo() { VectorF[] vertices; if (selectedGeoIsLine) { if (selectedGeo.Vertices.Length == 2) { world.removeGeo(selectedGeo); selectedGeo = null; loadObjectEditor(); return; } vertices = new VectorF[selectedGeo.Vertices.Length - 2]; for (int i = 0; i < selectedGeoVertex; i++) { vertices[i] = selectedGeo.Vertices[i]; } for (int i = selectedGeoVertex + 2; i < selectedGeo.Vertices.Length; i++) { vertices[i - 2] = selectedGeo.Vertices[i]; } } else if (selectedGeoVertex == -1) { world.removeGeo(selectedGeo); selectedGeo = null; loadObjectEditor(); return; } else { if (selectedGeo.Vertices.Length == 1) { world.removeGeo(selectedGeo); selectedGeo = null; loadObjectEditor(); return; } if (selectedGeo.Vertices.Length == 2) { vertices = new VectorF[1]; vertices[0] = selectedGeo.Vertices[1 - selectedGeoVertex]; } else if (selectedGeoVertex == 0) { vertices = new VectorF[selectedGeo.Vertices.Length - 2]; for (int i = 2; i < selectedGeo.Vertices.Length; i++) { vertices[i - 2] = selectedGeo.Vertices[i]; } } else if (selectedGeoVertex == selectedGeo.Vertices.Length - 1) { vertices = new VectorF[selectedGeo.Vertices.Length - 2]; for (int i = 0, max = selectedGeo.Vertices.Length - 2; i < max; i++) { vertices[i] = selectedGeo.Vertices[i]; } } else { vertices = new VectorF[selectedGeo.Vertices.Length - 2]; for (int i = 0, max = selectedGeoVertex - 1; i < max; i++) { vertices[i] = selectedGeo.Vertices[i]; } for (int i = selectedGeoVertex + 1; i < selectedGeo.Vertices.Length; i++) { vertices[i - 2] = selectedGeo.Vertices[i]; } } } world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridRemoveGeo); selectedGeo.Vertices = vertices; if (selectedGeo.Vertices.Length < 3) { selectedGeo.CloseLoop = false; selectedGeo.Display = false; } selectedGeo.refreshMath(new Vector2((float)tGeo.Width, (float)tGeo.Height)); world.Grid.Rect(selectedGeo.UpperLeft, selectedGeo.LowerRight, selectedGeo, world.gridAddGeo); selectedGeo = null; loadObjectEditor(); }
/// <summary>Moves the provided node to the specified coordinates.</summary> /// <param name="node">The node to move.</param> /// <param name="to">The coordinates to move the node to.</param> private void moveNode(Node node, VectorF to) { // remove from grid world.Grid.Point(node.Pos, node, world.gridRemoveNode); // remove attached segments from the grid foreach (Segment seg in world.Segments) { if (seg.Nodes[0] == node || seg.Nodes[1] == node) world.Grid.Line(seg.Nodes[0].Pos, seg.Nodes[1].Pos, seg, world.gridRemoveSegment); } node.Pos = to; // add back into grid if (world.Nodes.Contains(node)) world.Grid.Point(node.Pos, node, world.gridAddNode); // add attached segments back into the grid foreach (Segment seg in world.Segments) { if (seg.Nodes[0] == node || seg.Nodes[1] == node) { double q0 = (double)seg.EndLength[0] / (double)seg.Length; double q1 = (double)seg.EndLength[1] / (double)seg.Length; seg.refreshMath(); seg.EndLength[0] = (seg.State[0] == SegmentSkel.SegState.Complete) ? seg.Length : (FInt)((double)seg.Length * q0); seg.EndLength[1] = (seg.State[1] == SegmentSkel.SegState.Complete) ? seg.Length : (FInt)((double)seg.Length * q1); seg.refreshEndLocs(); world.Grid.Line(seg.Nodes[0].Pos, seg.Nodes[1].Pos, seg, world.gridAddSegment); } } }
private void moveHotspot(Hotspot hotspot, VectorF to) { // remove from grid world.Grid.Point(hotspot.Pos, hotspot, world.gridRemoveHotspot); hotspot.Pos = to; // add back into grid if (world.Hotspots.Contains(hotspot)) world.Grid.Point(hotspot.Pos, hotspot, world.gridAddHotspot); }
/// <summary>Creates a new instance of LevelEditorMode.</summary> /// <param name="graphics">The graphics device manager to use.</param> /// <param name="content">The content manager to use.</param> /// <param name="batch">The sprite batch to use.</param> /// <param name="bEffect">The basic effect to use.</param> public LevelEditorMode(GraphicsDeviceManager graphics, ContentManager content, SpriteBatch batch, BasicEffect bEffect) : base(graphics, content, batch, bEffect) { world = new World(true); world.Grid = new GridManager(1, 1, world); hoveredNode = null; selectedNode = null; hoveredSeg = null; selectedSeg = null; hoveredSegEnd = null; hoveredSegEndOwner = null; selectedSegEnd = null; hoveredGeo = null; hoveredGeoVertex = -1; hoveredGeoIsLine = false; selectedGeo = null; selectedGeoVertex = -1; selectedGeoIsLine = false; desktop = new Desktop(); lastClickedPoint = new VectorF(); dragOffset = new VectorF(); isDragging = false; }