public void DotProductTest() { Vector2 forward = new Vector2(0, 1); Vector2 back = new Vector2(0, -1); Vector2 right = new Vector2(1, 0); Vector2 left = new Vector2(-1, 0); Assert.AreEqual(1, forward.DotProduct(forward)); Assert.AreEqual(-1, forward.DotProduct(back)); Assert.AreEqual(0, forward.DotProduct(right)); Assert.AreEqual(0, forward.DotProduct(left)); }
private void AddImpulseContactPoint(PhysicsObject obj1, PhysicsObject obj2, Vector2 contactPoint, Vector2 normal, float penetration, int contactPoints, float dt) { Vector2 r0 = contactPoint - obj1.Center; Vector2 r1 = contactPoint - obj2.Center; Vector2 relativeVel = (obj1.LinearVelocity + obj1.AngularVelocity * r0.CrossProduct()) - (obj2.LinearVelocity + obj2.AngularVelocity * r1.CrossProduct()); float contactVel = Vector2.DotProduct(relativeVel, normal); if (contactVel > 0) { return; } float tmp1 = Vector2.VectorProduct(r0, normal); tmp1 *= tmp1; float tmp2 = Vector2.VectorProduct(r1, normal); tmp2 *= tmp2; float invMass = obj1.InvertedMass + obj2.InvertedMass + obj1.InvertedMomentOfInertia * tmp1 + obj2.InvertedMomentOfInertia * tmp2; const float allowedPenetration = 0.1f; const float biasFactor = 0.1f; float e = (dt == 0 ? 0 : 1 / dt) * System.Math.Max(0, penetration - allowedPenetration) * biasFactor; float j = System.Math.Max(0, (-contactVel + e) / (invMass * contactPoints)); Vector2 impulse = j * normal; obj1.ApplyImpulse(impulse, r0); }
private Vector2[] GetSupportPoints(Polygon polygon, Vector2 dir) { int count = 0; const float threshold = 1.0E-8f; double mind = 0; List <Vector2> support = new List <Vector2>(2); for (int i = 0; i < polygon.Points.Length; i++) { float d = Vector2.DotProduct(polygon.Points[i], dir); if (i == 0 || d < mind) { mind = d; } } for (int i = 0; i < polygon.Points.Length; i++) { float d = Vector2.DotProduct(polygon.Points[i], dir); if (d < (mind + threshold)) { support.Add(polygon.Points[i]); count++; if (count >= 2) { return(support.ToArray()); } } } return(support.ToArray()); }
/// <summary> /// Rotates the actor to face the given position /// </summary> /// <param name="position">The position the actor should be facing</param> public void LookAt(Vector2 position) { //Find the direction that the actor should look in Vector2 direction = (position - LocalPosition).Normalized; //Use the dotproduct to find the angle the actor needs to rotate float dotProd = Vector2.DotProduct(Forward, direction); if (Math.Abs(dotProd) > 1) { return; } float angle = (float)Math.Acos(dotProd); //Find a perpindicular vector to the direction Vector2 perp = new Vector2(direction.Y, -direction.X); //Find the dot product of the perpindicular vector and the current forward float perpDot = Vector2.DotProduct(perp, Forward); //If the result isn't 0, use it to change the sign of the angle to be either positive or negative if (perpDot != 0) { angle *= -perpDot / Math.Abs(perpDot); } Rotate(angle); }
/// <summary> /// Rotate this actor to face a position /// </summary> /// <param name="position">Position to face</param> public void LookAt(Vector2 position) { // Find the direction to look at Vector2 direction = (position - GlobalPosition).Normalized; // Get dotproduct between forward and direction to look float dotProduct = Vector2.DotProduct(Forward, direction); // If actor is already facing that direction, return if (dotProduct >= 1) { return; } // Get angle to face float angle = (float)Math.Acos(dotProduct); // Get perpendicular vector to direction Vector2 perpVector = new Vector2(-direction.Y, direction.X); // Get dotproduct between forward and perpendicular vector float perpDotProduct = Vector2.DotProduct(perpVector, Forward); // Negate angle if perDotProduct is negative if (perpDotProduct != 0) { angle *= perpDotProduct / Math.Abs(perpDotProduct); } SetRotation(angle + RotationAngle); }
private void PrintStateOfBox(StringBuilder b, PhysicalParticle box) { const double RadsToDegress = 180 / (double)Math.PI; b.AppendLine($" X: {box.Position.X}"); b.AppendLine($" Y: {box.Position.Y}"); b.AppendLine($" A: {box.Angle}\n"); if (debugInfoPage == 0) { b.AppendLine($" v_x: {box.Velocity.X}"); b.AppendLine($" v_y: {box.Velocity.Y}"); b.AppendLine($" w: {box.AngularVelocity}"); b.AppendLine($"\n F_x: {box.Force.X}"); b.AppendLine($" F_y: {box.Force.Y}"); b.AppendLine($" T: {box.Torque}"); b.AppendLine($"\nFC_x: {box.ConstraintForce.X}"); b.AppendLine($"FC_y: {box.ConstraintForce.Y}"); b.AppendLine($" TC: {box.ConstraintTorque}"); var angle = RadsToDegress * Vector2.DotProduct(box.ConstraintForce, box.Velocity) / (box.ConstraintForce.Magnitude * box.Velocity.Magnitude); b.AppendLine($"\n DOT: {angle}"); } else if (debugInfoPage == 1) { solver.DebugInfo(b, debugInfoPage, box); } }
public static long WhereVector(Vector2 beginPoint, Vector2 endPoint, Vector2 point) {//???????????? Vector2 segment = endPoint - beginPoint; Vector2 aimVec = point - beginPoint; if (Vector2.CrossProduct(segment, aimVec) > EPS) { return(1);//?????? } else if (Vector2.CrossProduct(segment, aimVec) < -EPS) { return(2);//????? } else if (Vector2.DotProduct(segment, aimVec) < -1 + EPS) { return(3);//?????????? } else if (segment.Length() < aimVec.Length()) { return(4);//???????? } else { return(5);//????? } }
public static Vector2 Projection(Vector2 beginPoint, Vector2 endPoint, Vector2 point)//???? { Vector2 segment = endPoint - beginPoint; decimal ratio = Vector2.DotProduct(point - beginPoint, segment) / segment.Length(); return(beginPoint + segment * ratio);//????? }
private static int Clip(Vector2 n, float c, ref Vector2[] pFace) { int sp = 0; Vector2[] outV = new Vector2[] { pFace[0], pFace[1] }; float d1 = Vector2.DotProduct(n, pFace[0]) - c; float d2 = Vector2.DotProduct(n, pFace[1]) - c; if (d1 <= 0) { outV[sp++] = pFace[0]; } if (d2 <= 0) { outV[sp++] = pFace[1]; } if (d1 * d2 < 0) { float alpha = d1 / (d1 - d2); outV[sp] = pFace[0] + alpha * (pFace[1] - pFace[0]); sp++; } pFace = outV; System.Diagnostics.Debug.Assert(sp != 3); return(sp); }
private static void FindIncidentFace(out Vector2[] pV, PolygonMesh pRef, PolygonMesh pInc, int pIndex) { Vector2 referenceNormal = pRef.Normals[pIndex]; var iMat = pInc.Body.GameObject.RotationMatrix; referenceNormal = pRef.Body.GameObject.RotationMatrix * referenceNormal; referenceNormal = iMat.Transpose() * referenceNormal; int incidentFace = 0; float min = float.MaxValue; for (int i = 0; i < pInc.Vertices.Length; i++) { float dot = Vector2.DotProduct(referenceNormal, pInc.Normals[i]); if (dot < min) { min = dot; incidentFace = i; } } pV = new Vector2[2]; pV[0] = iMat * pInc.Vertices[incidentFace] + pInc.Body.AABB.Center; incidentFace = incidentFace + 1 >= pInc.Vertices.Length ? 0 : incidentFace + 1; pV[1] = iMat * pInc.Vertices[incidentFace] + pInc.Body.AABB.Center; }
private static float FindAxisLeastPenetration(out int pIndex, PolygonMesh pA, PolygonMesh pB) { float best = float.MinValue; pIndex = 0; var aMat = pA.Body.GameObject.RotationMatrix; var bMat = pB.Body.GameObject.RotationMatrix; for (int i = 0; i < pA.Vertices.Length; i++) { Vector2 normal = pA.Normals[i]; Vector2 orientedNormal = aMat * normal; Mathematics.Matrix2X2 buT = bMat.Transpose(); normal = buT * orientedNormal; Vector2 support = pB.GetSupport(-normal); Vector2 vertex = pA.Vertices[i]; vertex = aMat * vertex + pA.Body.AABB.Center; vertex -= pB.Body.AABB.Center; vertex = buT * vertex; float d = Vector2.DotProduct(normal, support - vertex); if (d > best) { best = d; pIndex = i; } } return(best); }
private void mainPB_MouseMove(object sender, MouseEventArgs e) { // GC.Collect(); if (this.e0 != null) { if (photoCB.SelectedIndex != -1 && photoMoveRBTN.Checked) { if (toDoObj == toDo.Move) { this.Scene.Photos[photoCB.SelectedIndex].Move(e.X - e0.X, e.Y - e0.Y); } else if (toDoObj == toDo.Resize) { this.Scene.Photos[photoCB.SelectedIndex].Process( new ScalingFilter(this.Scene.Photos[photoCB.SelectedIndex].Width + e.X - e0.X, this.Scene.Photos[photoCB.SelectedIndex].Height + e.Y - e0.Y)); } else { Vector2 p = Vector2.Normolize(new Vector2(e.X - this.Scene.Photos[photoCB.SelectedIndex].X , e.Y - this.Scene.Photos[photoCB.SelectedIndex].Y)); float cosOX = Vector2.DotProduct(p, new Vector2(1, 0)); float cosOY = Vector2.DotProduct(p, new Vector2(0, 1)); double angle = 0; if (cosOX >= 0 && cosOY >= 0) { angle = Math.Acos(cosOX); } else if (cosOX <= 0 && cosOY >= 0) { angle = Math.Acos(cosOY) + Math.PI / 2; } else if (cosOX <= 0 && cosOY <= 0) { angle = 3 * Math.PI / 2 - Math.Acos(cosOX) + Math.PI / 2; } else { angle = -Math.Acos(cosOX); } //angle = -angle; this.Scene.Photos[photoCB.SelectedIndex].Process( new RotateFilter((float)angle)); } this.Scene.UpdatePhotos(); } else if (lightCB.SelectedIndex != -1 && !photoMoveRBTN.Checked) { if (this.Scene.Map.Light[lightCB.SelectedIndex] is Spotlight) { (this.Scene.Map.Light[lightCB.SelectedIndex] as Spotlight).Move(e.X - e0.X, e.Y - e0.Y); } this.Scene.UpdateLightingMap(); } Draw(); this.e0 = e; } }
/// <summary> /// Finds the angle in radians between the Vector2 and specified other Vector2. /// </summary> /// <param name="compareTo">Other Vector2 to compare to for angle calculation.</param> public float AngleBetween(Vector2 compareTo) { // Normalize both Vector2s Vector2 a = GetNormalized(); Vector2 b = compareTo.GetNormalized(); return((float)Math.Acos(a.DotProduct(b))); }
public static Line2 FromPointAndDirection(Vector2 point, Vector2 direction) { var normal = direction.Rotate90Positive().Normalize(); var distanceFromOriginToPointProjectedOnNormal = Vector2.DotProduct(point, normal); return(new Line2(normal, distanceFromOriginToPointProjectedOnNormal)); }
_projection Project(Vector2 onto) { float min = onto.DotProduct(points[0]); float max = min; for (int i = 1; i < points.Count; i++) { float p = onto.DotProduct(points[i]); if (p < min) { min = p; } else if (p > max) { max = p; } } return(new _projection(min, max)); }
public static Vector2 PointProjectionToLine(Vector2 point, Vector2 p1, Vector2 p2, out bool isInside) { var a = point - p1; var b = (p2 - p1) / Vector2.Distance(p1, p2); point = Vector2.DotProduct(a, b) * b + p1; isInside = point.X >= Mathf.Min(p1.X, p2.X) && point.X <= Mathf.Max(p1.X, p2.X) && point.Y >= Mathf.Min(p1.Y, p2.Y) && point.Y <= Mathf.Max(p1.Y, p2.Y); return(point); }
private Vector2 Edge_GetClosestPoint(Vector2 p, Vector2 a, Vector2 b) { Vector2 ab = b - a; Vector2 ap = p - a; float ab_ab = Vector2.DotProduct(ab, ab); float ab_ap = Vector2.DotProduct(ab, ap); float t = MathHelper.Clamp(ab_ap / ab_ab, 0.0f, 1.0f); return(a + t * ab); }
public void OperationsTest() { Assert.That(Vector2.One * Vector2.Zero, Is.EqualTo(Vector2.Zero)); Assert.That(Vector2.One - Vector2.One, Is.EqualTo(Vector2.Zero)); Assert.That(0.5f * (Vector2.One * 2), Is.EqualTo(Vector2.One)); Assert.That(Vector2.Half / Vector2.Half, Is.EqualTo(Vector2.One)); Assert.That(Vector2.One / 2, Is.EqualTo(Vector2.Half)); Assert.That(Vector2.Half + Vector2.Half, Is.EqualTo(Vector2.One)); Assert.That(-Vector2.One, Is.EqualTo(new Vector2(-1))); Assert.That(Vector2.DotProduct(Vector2.Half, Vector2.Half), Is.EqualTo(0.5f)); Assert.That(Vector2.CrossProduct(Vector2.Half, Vector2.Half), Is.EqualTo(0)); }
//C++ TO C# CONVERTER TODO TASK: The implementation of the following method could not be found: // bool isPointInside(Ogre::Vector2 point); public bool isPointInside(Vector2 point) { // Compute vectors Vector2 v0 = p(2) - p(0); Vector2 v1 = p(1) - p(0); Vector2 v2 = point - p(0); // Compute dot products Real dot00 = v0.SquaredLength; Real dot01 = v0.DotProduct(v1); Real dot02 = v0.DotProduct(v2); Real dot11 = v1.SquaredLength; Real dot12 = v1.DotProduct(v2); // Compute barycentric coordinates Real invDenom = 1 / (dot00 * dot11 - dot01 * dot01); Real u = (dot11 * dot02 - dot01 * dot12) * invDenom; Real v = (dot00 * dot12 - dot01 * dot02) * invDenom; // Check if point is in triangle return((u >= 0) && (v >= 0) && (u + v - 1 <= 0)); }
public static float SqrDistanceFromPointToSegment(Vector2 v, Vector2 w, Vector2 p) { var l2 = (w - v).SqrLength; if (l2 == 0) { return((p - v).SqrLength); } var t = Mathf.Max(0, Mathf.Min(1, Vector2.DotProduct(p - v, w - v) / l2)); var proj = v + t * (w - v); return((p - proj).SqrLength); }
public bool CheckTargetInSight() { if (Target == null) return false; Vector2 direction = Position - Target.Position; if (Vector2.DotProduct(Forward, direction) < 0) return true; else if (Vector2.DotProduct(Forward, direction) > 0.1) return false; return false; }
// * // * Equivalent of Ogre::Vector3::angleBetween, applied to Ogre::Vector2 // public static Radian angleBetween(Vector2 v1, Vector2 v2) { float lenProduct = v1.Length * v2.Length; // Divide by zero check if (lenProduct < 1e-6f) { lenProduct = 1e-6f; } float f = v1.DotProduct(v2) / lenProduct; f = Math_Clamp(f, -1.0f, 1.0f); return(Math.ACos(f)); }
public PhysicsObject(float mass, Polygon polygon, Vector2 linearVelocity = default(Vector2), float angularVelocity = 0.0f) { if (mass < 0) { throw new ArgumentException("mass", "Die Masse muss positiv oder 0 sein."); } if (!polygon.IsValid) { throw new ArgumentException("polygon", "Das übergebene Polygon ist nicht gültig."); } Polygon = polygon; startPolygon = polygon; Mass = mass; forces = new Vector2(0, 0); torques = 0; radius = 0; Center = polygon.Center; startCenter = Center; for (int i = 0; i < polygon.Points.Length; i++) { float dist = (Center - polygon.Points[i]).Length; if (dist > radius) { radius = dist; } } float denom = 0; float num = 0; for (int i = 0; i < polygon.Points.Length - 1; i++) { Vector2 a = polygon.Points[i + 1] - Center; Vector2 b = polygon.Points[i] - Center; float f = System.Math.Abs(a.X * b.Y - a.Y * b.X); denom += f * (Vector2.DotProduct(a, a) + Vector2.DotProduct(a, b) + Vector2.DotProduct(b, b)); num += f; } MomentOfInertia = (mass * denom) / (6 * num); InvertedMass = mass == 0 ? 0 : 1.0f / mass; InvertedMomentOfInertia = MomentOfInertia == 0 ? 0 : 1.0f / MomentOfInertia; LinearVelocity = linearVelocity; AngularVelocity = angularVelocity; }
public bool CheckTargetInSight() { if (Target == null) { return(false); } Vector2 direction = Vector2.Normalize(LocalPosition - Target.LocalPosition); if (Vector2.DotProduct(Forward, direction) > 1) { return(true); } return(false); }
public bool CheckTargetInSight() { if (Target == null) { return(false); } Vector3 direction = Vector3.Normalize(Transform.Position - Target.Transform.Position); if (Vector2.DotProduct(Forward, direction) > 0) { return(true); } return(false); }
public override void HandleColliding(PlatformObject obj, Vector2 move) { if (obj is ChemBlock) { ChemBlock block = (ChemBlock)obj; if (!IsBondedWith(block) && nailDuration > 0) { Vector2 moveDir = move; moveDir.Normalize(); if (nailDirection.DotProduct(moveDir) > 0.5f) { NailOnto(block); nailDuration = 0; } } } }
/// <summary> /// Calculates the squared distance between a given point and a given ray. /// </summary> /// <param name="point">A <see cref="Vector2"/> instance.</param> /// <param name="ray">A <see cref="Ray"/> instance.</param> /// <returns>The squared distance between the point and the ray.</returns> public static double SquaredDistance(Vector2 point, Ray ray) { Vector2 diff = point - ray.Origin; double t = Vector2.DotProduct(diff, ray.Direction); if (t <= 0.0f) { t = 0.0f; } else { t /= ray.Direction.GetLengthSquared(); diff -= t * ray.Direction; } return(diff.GetLengthSquared()); }
/// <summary> /// Find the intersection of a ray and a sphere. /// Only works with unit rays (normalized direction)!!! /// </summary> /// <remarks> /// This is the optimized Ray-Sphere intersection algorithms described in "Real-Time Rendering". /// </remarks> /// <param name="ray">The ray to test.</param> /// <param name="t"> /// If intersection accurs, the function outputs the distance from the ray's origin /// to the closest intersection point to this parameter. /// </param> /// <returns>Returns True if the ray intersects the sphere. otherwise, <see langword="false"/>.</returns> public bool FindIntersections(Ray ray, ref double t) { // Only gives correct result for unit rays. //Debug.Assert(MathUtils.ApproxEquals(1.0f, ray.Direction.GetLength()), "Ray direction should be normalized!"); // Calculates a vector from the ray origin to the sphere center. Vector2 diff = this.center - ray.Origin; // Compute the projection of diff onto the ray direction double d = Vector2.DotProduct(diff, ray.Direction); double diffSquared = diff.GetLengthSquared(); double radiusSquared = this.radius * this.radius; // First rejection test : // if d<0 and the ray origin is outside the sphere than the sphere is behind the ray if ((d < 0.0f) && (diffSquared > radiusSquared)) { return(false); } // Compute the distance from the sphere center to the projection double mSquared = diffSquared - d * d; // Second rejection test: // if mSquared > radiusSquared than the ray misses the sphere if (mSquared > radiusSquared) { return(false); } double q = (double)System.Math.Sqrt(radiusSquared - mSquared); // We are interested only in the first intersection point: if (diffSquared > radiusSquared) { // If the origin is outside the sphere t = d - q is the first intersection point t = d - q; } else { // If the origin is inside the sphere t = d + q is the first intersection point t = d + q; } return(true); }
public void LookAt(Vector2 position) { Vector2 direction = (position - LocalPosition).Normalized; float dotProd = Vector2.DotProduct(Forward, direction); if (Math.Abs(dotProd) > 1) return; float angle = (float)Math.Acos(dotProd); Vector2 perp = new Vector2(direction.Y, -direction.X); float perpDot = Vector2.DotProduct(perp, Forward); if (perpDot != 0) angle *= -perpDot / Math.Abs(perpDot); Rotate(angle); }
//allows the enemy to detect a target public bool GetTargetInSight(float maxAngle, float maxDistance) { if (Target == null) { return(false); } Vector2 direction = Target.LocalPosition - LocalPosition; float distance = (Target.LocalPosition - LocalPosition).Magnitude; float angle = (float)Math.Acos(Vector2.DotProduct(Forward, direction.Normalized)); if (angle <= maxAngle && distance <= maxDistance) { return(true); } return(false); }
// Calculate the projection of a polygon on an axis and returns it as a [min, max] interval public static void ProjectPolygon(Vector2 axis, Polygon polygon, ref float min, ref float max) { // To project a point on an axis use the dot product float d = axis.DotProduct(polygon.Points[0]); min = d; max = d; for (int i = 0; i < polygon.Points.Count; i++) { d = polygon.Points[i].DotProduct(axis); if (d < min) { min = d; } else { if (d > max) { max = d; } } } }
// Check if polygon A is going to collide with polygon B for the given velocity public static PolygonCollisionResult PolygonCollision(Polygon polygonA, Polygon polygonB, Vector2 velocity) { PolygonCollisionResult result = new PolygonCollisionResult(); result.Intersect = true; result.WillIntersect = true; int edgeCountA = polygonA.Edges.Count; int edgeCountB = polygonB.Edges.Count; float minIntervalDistance = float.PositiveInfinity; Vector2 translationAxis = new Vector2(); Vector2 edge; // Loop through all the edges of both polygons for (int edgeIndex = 0; edgeIndex < edgeCountA + edgeCountB; edgeIndex++) { if (edgeIndex < edgeCountA) { edge = polygonA.Edges[edgeIndex]; } else { edge = polygonB.Edges[edgeIndex - edgeCountA]; } // ===== 1. Find if the polygons are currently intersecting ===== // Find the axis perpendicular to the current edge Vector2 axis = new Vector2(-edge.y, edge.x); axis.Normalize(); // Find the projection of the polygon on the current axis float minA = 0; float minB = 0; float maxA = 0; float maxB = 0; ProjectPolygon(axis, polygonA, ref minA, ref maxA); ProjectPolygon(axis, polygonB, ref minB, ref maxB); // Check if the polygon projections are currentlty intersecting if (IntervalDistance(minA, maxA, minB, maxB) > 0) result.Intersect = false; // ===== 2. Now find if the polygons *will* intersect ===== // Project the velocity on the current axis float velocityProjection = axis.DotProduct(velocity); // Get the projection of polygon A during the movement if (velocityProjection < 0) { minA += velocityProjection; } else { maxA += velocityProjection; } // Do the same test as above for the new projection float intervalDistance = IntervalDistance(minA, maxA, minB, maxB); if (intervalDistance > 0) result.WillIntersect = false; // If the polygons are not intersecting and won't intersect, exit the loop if (!result.Intersect && !result.WillIntersect) break; // Check if the current interval distance is the minimum one. If so store // the interval distance and the current distance. // This will be used to calculate the minimum translation Vector2 intervalDistance = Mathf.Abs(intervalDistance); if (intervalDistance < minIntervalDistance) { minIntervalDistance = intervalDistance; translationAxis = axis; Vector2 d = polygonA.Center - polygonB.Center; if (d.DotProduct(translationAxis) < 0) translationAxis = -translationAxis; } } // The minimum translation Vector2 can be used to push the polygons appart. // First moves the polygons by their velocity // then move polygonA by MinimumTranslationVector2. if (result.WillIntersect) result.MinimumTranslation = translationAxis * minIntervalDistance; return result; }