public override void Draw() { float x = 300, y = 200; x = Mouse.GetX() * 100; y = Mouse.GetY() * 100; Graphics.Clear(0.7f, 0.7f, 0.7f); // draw mouse line (RED) Graphics.SetColor(1, 0, 0); Graphics.Line(0, 0, x, y); // draw ray cast info (GREED) Graphics.SetPointSize(10); Graphics.SetColor(0, 1, 0); foreach (var item in rectList) { Ray2D ray = new Ray2D(0, 0, x, y); if (ray.Intersects(item, out var result)) { if (m_drawDebugInfo) { Graphics.Points(result.X, result.Y); } } } base.Draw(); }
public bool RayCast(Ray2D ray, out RayCastResult result) { bool existResult = false; result = new RayCastResult(); Queue <QuadTreeNode> queue = new Queue <QuadTreeNode>(); queue.Enqueue(this); Vector2 hitPoint; while (queue.Count != 0) { var leaf = queue.Dequeue(); // 当此节点 Zone 与所给 RectangleF 不相交时返回 null if (ray.Intersects(leaf.m_zone, out hitPoint) == false) { continue; } // 查看是否与此节点内的 item 有覆盖 foreach (var item in leaf.managedItems) { if (ray.Intersects(item.Zone, out hitPoint) && (existResult == false || Vector2.DistanceSquared(ray.Original, hitPoint) < Vector2.DistanceSquared(ray.Original, result.Intersection))) { existResult = true; result = new RayCastResult(hitPoint, item); } } // 查找子节点 for (int i = 0; i < 4; i++) { if (leaf.childern[i] != null && ray.Intersects(leaf.childern[i].Zone, out hitPoint)) { queue.Enqueue(leaf.childern[i]); } } } return(existResult); }
public LinkedList <RayCastResult> RayCastAll(Ray2D ray) { var outList = new LinkedList <RayCastResult>(); Queue <QuadTreeNode> queue = new Queue <QuadTreeNode>(); queue.Enqueue(this); Vector2 castResult; while (queue.Count != 0) { var leaf = queue.Dequeue(); // 当此节点 Zone 与所给 RectangleF 不相交时返回 null if (ray.Intersects(leaf.m_zone, out castResult) == false) { continue; } // 查看是否与此节点内的 item 有覆盖 foreach (var item in leaf.managedItems) { if (ray.Intersects(item.Zone, out castResult)) { outList.AddLast(new RayCastResult(castResult, item)); } } // 查找子节点 for (int i = 0; i < 4; i++) { if (leaf.childern[i] != null && ray.Intersects(leaf.childern[i].Zone, out castResult)) { queue.Enqueue(leaf.childern[i]); } } } return(outList); }
public override void Sense() { base.Sense(); EndPoints = new List<Vector2>(); for (int i = 0; i < 3; i++) //3 Feelers { float RotationOffset = 0f; if (i == 0) { RotationOffset = -0.4f; } else if (i == 2) { RotationOffset = 0.4f; } //Get Next Position Vector2 Velocity = pHost.Velocity; Velocity.X = (float)Math.Cos(pHost.Rotation + RotationOffset) * (MAX_RANGE + pHost.RotationalVelocity); Velocity.Y = (float)Math.Sin(pHost.Rotation + RotationOffset) * (MAX_RANGE + pHost.RotationalVelocity); Vector2 NextPosition = pHost.Position + Velocity; //Make Ray Ray2D R = new Ray2D(pHost.Position, NextPosition); Boolean HitWall = false; foreach (Actor A in pWorldActors) { if (A is BlockingActor) //If its a wall { //Get Distance float Distance = Vector2.Distance(A.Position, pHost.Position); if (Distance <= MAX_RANGE + 64 + pHost.RotationalVelocity) //In Range { Vector2 HitAt = R.Intersects(A.CollisionRectangle); //Check if it intersects if (HitAt != Vector2.Zero) { EndPoints.Add(HitAt); HitWall = true; DebugInformation += "Feeler(" + (i + 1).ToString() + ") - Touching Wall " + Vector2.Distance(HitAt, pHost.Position).ToString() + "\r\n"; } } } } if (!HitWall) { EndPoints.Add(NextPosition); DebugInformation += "Feeler(" + (i + 1).ToString() + ") - Not Touching Wall\r\n"; } } }
public LinkedList <RayCastResult> RayCastAll(Ray2D ray) { var outList = m_root.RayCastAll(ray); Vector2 castResult; foreach (var leaf in overFlowLeaf) { if (ray.Intersects(leaf.Zone, out castResult)) { outList.AddLast(new RayCastResult(castResult, leaf)); } } return(outList); }
public bool RayCast(Ray2D ray, out RayCastResult result) { bool existResult = m_root.RayCast(ray, out result); // check leaf not in world foreach (var leaf in overFlowLeaf) { if (ray.Intersects(leaf.Zone, out Vector2 hitPoint) && (existResult == false || Vector2.DistanceSquared(ray.Original, hitPoint) < Vector2.DistanceSquared(ray.Original, result.Intersection))) { existResult = true; result = new RayCastResult(hitPoint, leaf); } } return(existResult); }
internal static int smethod_0(Ray2D ray, Polyline2D polyline) { int num1 = 0; int num2 = polyline.Count + (polyline.Closed ? 1 : 0); int count = polyline.Count; Point2D start = polyline[0]; for (int index = 1; index < num2; ++index) { Point2D end = polyline[index % count]; Segment2D b = new Segment2D(start, end); if (Ray2D.Intersects(ray, b)) { ++num1; } start = end; } return(num1); }
public void IntersectsBoundingRectangle(Ray2D ray, BoundingRectangle boundingRectangle, bool expectedResult, Point2 firstExpectedIntersectionPoint, Point2 secondExpectedIntersectionPoint) { float rayNearDistance, rayFarDistance; var actualResult = ray.Intersects(boundingRectangle, out rayNearDistance, out rayFarDistance); Assert.AreEqual(expectedResult, actualResult); if (actualResult) { var firstActualIntersectionPoint = ray.Position + ray.Direction * rayNearDistance; Assert.AreEqual(firstExpectedIntersectionPoint, firstActualIntersectionPoint); var secondActualIntersectionPoint = ray.Position + ray.Direction * rayFarDistance; Assert.AreEqual(secondExpectedIntersectionPoint, secondActualIntersectionPoint); } else { Assert.IsTrue(float.IsNaN(rayNearDistance)); Assert.IsTrue(float.IsNaN(rayFarDistance)); } }
internal static bool IsInside(Point2D p, Polyline3D polyline) { if (polyline == null) { return(false); } int num1 = 0; Ray2D a = new Ray2D(p, Vector2D.XAxis); int num2 = polyline.Count + (polyline.Closed ? 1 : 0); int count = polyline.Count; Point3D point3D1 = polyline[0]; for (int index = 1; index < num2; ++index) { Point3D point3D2 = polyline[index % count]; Segment2D b = new Segment2D(point3D1.X, point3D1.Y, point3D2.X, point3D2.Y); if (Ray2D.Intersects(a, b)) { ++num1; } point3D1 = point3D2; } return(num1 % 2 == 1); }
private Vector2 GetArrowScreenBorderPosition(GraphicsContext graphicsContext, Vector2 entityPosition) { Vector2 direction = entityPosition - CCamera2D.Active.Position; Ray2D ray = new Ray2D(graphicsContext.ScreenSize / 2f, Vector2.Normalize(direction)); // ray from screen center to the direction of the drop if (!Check.IsValid(ray)) { return -Vector2.One * 10000; // invalid number } RectangleF screenArea = new RectangleF(graphicsContext.ScreenArea).Inflate(-16); Vector2 hitPosition; if (ray.Intersects(screenArea.GetSideSegment(Direction2D.Left), out hitPosition) || ray.Intersects(screenArea.GetSideSegment(Direction2D.Right), out hitPosition) || ray.Intersects(screenArea.GetSideSegment(Direction2D.Up), out hitPosition) || ray.Intersects(screenArea.GetSideSegment(Direction2D.Down), out hitPosition)) { return hitPosition; } throw new InvalidOperationException(""); }
private Segment2D GetLaserSegment(CTransform2D rayStartTransform, EntityWorld entityWorld) { Ray2D ray = new Ray2D(rayStartTransform); RectangleF cameraArea = SkypieaConstants.GetAdjustedCameraArea(CCamera2D.Active); Vector2 rayEndPoint; if (!ray.Intersects(cameraArea, out rayEndPoint)) { return new Segment2D(-Vector2.One * 1000, -Vector2.One * 1000); } return new Segment2D(ray.Position, rayEndPoint); }
/// <summary> /// Handles attacking with a ranged weapon. /// </summary> /// <param name="weapon">The weapon to attack with. Cannot be null.</param> /// <param name="target">The target to attack. Can be null.</param> void AttackRanged(ItemEntity weapon, Character target) { if (weapon == null) { Debug.Fail("Weapon should not be null..."); return; } // We can't do anything with ranged attacks if no target is given if (target == null) { TrySend(GameMessage.CannotAttackNeedTarget, ServerMessageType.GUI); return; } Ray2D ray = new Ray2D(this, Position, target.Position, Map.Spatial); Vector2 rayCollideWall; // FUTURE: Use to create some sort of wasted ammo on a wall or something. e.g. Grenade item explodes on walls. bool hasHitWall = ray.Intersects<WallEntity>(out rayCollideWall); if (hasHitWall) { TrySend(GameMessage.CannotAttackNotInSight, ServerMessageType.GUI); return; } List<ISpatial> rayCollideCharacters; // Use IntersectsMany here if you want to damage all characters in the attack path bool hasHitCharacter = ray.Intersects<Character>(out rayCollideCharacters); if (hasHitCharacter) { var ammoUsed = false; // Check for the needed ammo switch (weapon.WeaponType) { case WeaponType.Projectile: // Grab projectile ammo out of the inventory first if possible to avoid having to constantly reload var invAmmo = Inventory.FirstOrDefault(x => weapon.CanStack(x.Value)); if (invAmmo.Value != null) Inventory.DecreaseItemAmount(invAmmo.Key); else weapon.Destroy(); ammoUsed = true; break; case WeaponType.Ranged: // By default, guns won't use ammo. But if you want to require guns to use ammo, you can do so here ammoUsed = true; break; } if (!ammoUsed) return; foreach (var character in rayCollideCharacters) { var c = character as Character; if (!Alliance.CanAttack(c.Alliance)) continue; // Attack using (var charAttack = ServerPacket.CharAttack(MapEntityIndex, c.MapEntityIndex, weapon.ActionDisplayID)) { Map.SendToArea(this, charAttack, ServerMessageType.MapEffect); } OnAttacked(); if (Attacked != null) Attacked.Raise(this, EventArgs.Empty); AttackApplyReal(c); } } }