/// <summary> /// Determines if a circle and rectangle intersect. /// </summary> /// <param name="center">The center of the circle.</param> /// <param name="radius">The radius of the circle.</param> /// <param name="rectangle">The rectangle.</param> /// <returns>Returns a <see cref="Vector2" /> representing the normal if a collision occurs; otherwise <c>null</c>.</returns> public static Vector2? GetCircleRectangleCollisionNormal(Vector2 center, float radius, RectangleF rectangle) { var contact = center; if (contact.X < rectangle.Left) contact.X = rectangle.Left; if (contact.X > rectangle.Right) contact.X = rectangle.Right; if (contact.Y < rectangle.Top) contact.Y = rectangle.Top; if (contact.Y > rectangle.Bottom) contact.Y = rectangle.Bottom; var v = new Vector2(contact.X - center.X, contact.Y - center.Y); var length = v.Length(); return length > 0 && length < radius ? v/length : (Vector2?) null; }
public virtual void DrawLine(Point2f start, Point2f end, Colorf color, float padding = 2.0f) { //draw line with start and end position //padding means the width of line //color.Alpha means the opacity of line //first, we compute the matrix of world transform var transform = new GuiTransform(); var vector = new System.Numerics.Vector2(end.X - start.X, end.Y - start.Y); //1.compute the scale component, x-component is euqal the length of line, y-component is equal the padding transform.World = Matrix4x4.CreateScale(vector.Length(), padding, 1.0f); //2.compute the angle of rotate, we only rotate it at the z-axis transform.World *= Matrix4x4.CreateRotationZ((float)Math.Atan2(vector.Y, vector.X), new System.Numerics.Vector3(0, padding * 0.5f, 0)); //3.compute the translation, the position of start, but the y is start.y - padding * 0.5f transform.World *= Matrix4x4.CreateTranslation(new System.Numerics.Vector3(start.X, start.Y - padding * 0.5f, 0)); //4.keep transform matrix data transform.World *= Transform; //set project matrix transform.Project = mProject; //second, we set the render config var renderConfig = new GuiRenderConfig() { Color = color, Config = new Vector4(0) }; //update buffer mTransformBuffer.Update(transform); mRenderConfigBuffer.Update(renderConfig); //set buffer and shader mDevice.SetVertexBuffer(mSquareVertexBuffer); mDevice.SetIndexBuffer(mSquareIndexBuffer); mDevice.SetBuffer(mTransformBuffer, mTransformBufferSlot, GpuShaderType.All); mDevice.SetBuffer(mRenderConfigBuffer, mRenderConfigBufferSlot, GpuShaderType.All); //draw mDevice.DrawIndexed(6, 0, 0); }
private List <System.Numerics.Vector2> CalculatePoints(System.Numerics.Vector2 start, System.Numerics.Vector2 middle, System.Numerics.Vector2 end, int accuracy) { List <System.Numerics.Vector2> result = new List <System.Numerics.Vector2>(); if (Utilities.IsCollinear(start, middle, end)) { result.Add(start); result.Add(middle); } else { System.Numerics.Vector2 center = Utilities.CalculateCircleCenter(start, middle, end); // Debug.Log($"{center:F6}, r={radius:F6}, A={Utilities.OsuPixelToScreenPoint(slider.SliderPoints[0]):F6}, B={Utilities.OsuPixelToScreenPoint(slider.SliderPoints[1]):F6}, C={Utilities.OsuPixelToScreenPoint(slider.SliderPoints[2]):F6}"); System.Numerics.Vector2 OA = new System.Numerics.Vector2(start.X - center.X, start.Y - center.Y); System.Numerics.Vector2 OB = new System.Numerics.Vector2(middle.X - center.X, middle.Y - center.Y); System.Numerics.Vector2 OC = new System.Numerics.Vector2(end.X - center.X, end.Y - center.Y); float radius = OA.Length(); float angleCcwOaOb = Utilities.CalculateOrientedAngle(OA, OB); if (angleCcwOaOb < 0) { angleCcwOaOb += 2 * (float)Math.PI; } float angleCcwOaOc = Utilities.CalculateOrientedAngle(OA, OC); if (angleCcwOaOc < 0) { angleCcwOaOc += 2 * (float)Math.PI; } if (angleCcwOaOb > angleCcwOaOc) { angleCcwOaOc -= 2 * (float)Math.PI; } float segmentAngle = angleCcwOaOc / accuracy; float currentAngle = Mathf.Atan2(OA.Y, OA.X); for (int i = 0; i < accuracy; i++) { result.Add(new System.Numerics.Vector2(center.X + radius * Mathf.Cos(currentAngle), center.Y + radius * Mathf.Sin(currentAngle))); currentAngle += segmentAngle; } } return(result); }
[MethodImpl(MethodImplOptions.AggressiveInlining)] public static FLOAT Length(VECTOR v) { return(v.Length()); }
internal override void SolveVelocityConstraints(ref TimeStep step) { Body b = _bodyB; XForm xf1; b.GetXForm(out xf1); Vector2 r = MathUtils.Multiply(ref xf1.R, _localAnchor - b.GetLocalCenter()); // Cdot = v + cross(w, r) Vector2 Cdot = b._linearVelocity + MathUtils.Cross(b._angularVelocity, r); Vector2 impulse = MathUtils.Multiply(ref _mass, -(Cdot + _beta * _C + _gamma * _impulse)); Vector2 oldImpulse = _impulse; _impulse += impulse; float maxImpulse = step.dt * _maxForce; if (_impulse.LengthSquared() > maxImpulse * maxImpulse) { _impulse *= maxImpulse / _impulse.Length(); } impulse = _impulse - oldImpulse; b._linearVelocity += b._invMass * impulse; b._angularVelocity += b._invI * MathUtils.Cross(r, impulse); }