Quad QuadMinA(Tri tri, out Tri neighbor) { List <Tri> neighbors = (from t in Tris where IsNeighbor(tri, t) select t).ToList(); if (neighbors.Count == 0) { neighbor = null; return(null); } Triangle t1 = tri.ToTriangle(Nodes); //List<Triangle> neighborsT = new List<Triangle>(neighbors.Count); List <Quadrangle> neighborsQ = new List <Quadrangle>(neighbors.Count); foreach (Tri item in neighbors) { neighborsQ.Add(new Quadrangle(t1, item.ToTriangle(Nodes)) { Id = item.Id }); } List <Quadrangle> sortQ = (from q in neighborsQ orderby q.MaxAngleDeg select q).ToList(); Quadrangle q1 = sortQ[0]; neighbor = null; foreach (Tri item in neighbors) { if (item.Id == q1.Id) { neighbor = item; } } return(new Quad(((Node)q1.Vertex1).Id, ((Node)q1.Vertex2).Id, ((Node)q1.Vertex3).Id, ((Node)q1.Vertex4).Id)); }
private static void DrawNoteGroupOutline(ScoreRendererBase renderer, Quadrangle noteGroupBounds, NoteOrRest element) { renderer.DrawLine(noteGroupBounds.NW, noteGroupBounds.NE, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.NE, noteGroupBounds.SE, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.SE, noteGroupBounds.SW, new Pen(Color.Red), element); renderer.DrawLine(noteGroupBounds.SW, noteGroupBounds.NW, new Pen(Color.Red), element); }
public static bool RectTransformContain(RectTransform area, RectTransform test) { if (area == null || test == null) { return(false); } var worldcornersA = new Vector3[4]; area.GetWorldCorners(worldcornersA); var worldcornersB = new Vector3[4]; test.GetWorldCorners(worldcornersB); var a = new Quadrangle(worldcornersA[0].x, worldcornersA[0].y, worldcornersA[2].x, worldcornersA[2].y); var b = new Quadrangle(worldcornersB[0].x, worldcornersB[0].y, worldcornersB[2].x, worldcornersB[2].y); if (a.minX > b.maxX || a.maxX < b.minX || a.minY > b.maxY || a.maxY < b.minY) { return(false); } else { return(true); } }
public static Quadrangle GetBounds(this IEnumerable <Note> notes, ScoreRendererBase renderer) { if (!notes.Any()) { return(default(Quadrangle)); } var boundsCollection = notes.Select(n => n.GetBounds(renderer)).ToArray(); var bounds = new Quadrangle( boundsCollection.Last().NE, boundsCollection.First().NW, boundsCollection.Last().SE, boundsCollection.First().SW); var lowestB = bounds.SW.Y > bounds.SE.Y ? bounds.SW.Y : bounds.SE.Y; var highestB = bounds.NW.Y < bounds.NE.Y ? bounds.NW.Y : bounds.NE.Y; var lowest = boundsCollection.Max(b => b.SW.Y); var highest = boundsCollection.Min(b => b.NW.Y); var deltaYL = lowest - lowestB; var deltaYH = highest - highestB; return(new Quadrangle( new Point(bounds.NE.X, bounds.NE.Y + deltaYH), new Point(bounds.NW.X, bounds.NW.Y + deltaYH), new Point(bounds.SE.X, bounds.SE.Y + deltaYL), new Point(bounds.SW.X, bounds.SW.Y + deltaYL))); }
void RescaleWidgets(Quadrangle originalHull, bool hullInFirstWidgetSpace, Vector2 hullsPivotPoint, List <Widget> widgets, int controlPointIndex, Vector2 curMousePos, Vector2 prevMousePos, bool proportional) { Utils.ApplyTransformationToWidgetsGroupOobb( sv.Scene, widgets, hullsPivotPoint, hullInFirstWidgetSpace, curMousePos, prevMousePos, (originalVectorInOobbSpace, deformedVectorInOobbSpace) => { Vector2 deformationScaleInOobbSpace = new Vector2( Math.Abs(originalVectorInOobbSpace.X) < Mathf.ZeroTolerance ? 1 : deformedVectorInOobbSpace.X / originalVectorInOobbSpace.X, Math.Abs(originalVectorInOobbSpace.Y) < Mathf.ZeroTolerance ? 1 : deformedVectorInOobbSpace.Y / originalVectorInOobbSpace.Y ); if (proportional) { deformationScaleInOobbSpace.X = (deformationScaleInOobbSpace.X + deformationScaleInOobbSpace.Y) / 2; deformationScaleInOobbSpace.Y = deformationScaleInOobbSpace.X; } if (!LookupInvolvedAxes[controlPointIndex][0]) { deformationScaleInOobbSpace.X = proportional ? deformationScaleInOobbSpace.Y : 1; } if (!LookupInvolvedAxes[controlPointIndex][1]) { deformationScaleInOobbSpace.Y = proportional ? deformationScaleInOobbSpace.X : 1; } return(Matrix32.Scaling(deformationScaleInOobbSpace)); } ); }
public MatchResult(string tpl_type, Quadrangle quadrangle) : this(csSmartIdEnginePINVOKE.new_MatchResult__SWIG_2(tpl_type, Quadrangle.getCPtr(quadrangle)), true) { if (csSmartIdEnginePINVOKE.SWIGPendingException.Pending) { throw csSmartIdEnginePINVOKE.SWIGPendingException.Retrieve(); } }
internal void CalcContour() { if (Type == TypeFound.Круглый) { return; } Point2d v1 = new Point2d(-0.5 * B, -0.5 * L); Point2d v2 = new Point2d(-0.5 * B, 0.5 * L); Point2d v3 = new Point2d(0.5 * B, 0.5 * L); Point2d v4 = new Point2d(0.5 * B, -0.5 * L); double alfa = DegToRad(AlfaDeg); double x = v1.X; double y = v1.Y; v1.X = x * Math.Cos(alfa) - y * Math.Sin(alfa) + X; v1.Y = x * Math.Sin(alfa) + y * Math.Cos(alfa) + Y; x = v2.X; y = v2.Y; v2.X = x * Math.Cos(alfa) - y * Math.Sin(alfa) + X; v2.Y = x * Math.Sin(alfa) + y * Math.Cos(alfa) + Y; x = v3.X; y = v3.Y; v3.X = x * Math.Cos(alfa) - y * Math.Sin(alfa) + X; v3.Y = x * Math.Sin(alfa) + y * Math.Cos(alfa) + Y; x = v4.X; y = v4.Y; v4.X = x * Math.Cos(alfa) - y * Math.Sin(alfa) + X; v4.Y = x * Math.Sin(alfa) + y * Math.Cos(alfa) + Y; Contour = new Quadrangle(v1, v2, v3, v4); }
/// <summary> /// Konstruktor szescioparametrowy. /// </summary> /// <param name="yBegin">Wysokosc poczatku obiektu.</param> /// <param name="yEnd">Wysokosc konca obiektu.</param> /// <param name="hitBound">Prostokat opisujacy obiekt.</param> /// <param name="soldierNum">Liczba zolnierzy w baraku.</param> /// <param name="type">Typ baraku.</param> /// <param name="collisionRectangle">Lista prostokatow z ktorymi moga wystapic zderzenia.</param> public BarrackTile(float yBegin, float yEnd, float viewXShift, Quadrangle hitBound, int soldierNum, int generalNum, int type, List <Quadrangle> collisionRectangle) : base(yBegin, yEnd, viewXShift, hitBound, soldierNum, generalNum, type, collisionRectangle) { //przy starcie instalacja nie jest zniszczona. enemyState = EnemyInstallationState.Intact; }
public Polygon ConstructPolygon(List <Coordinate> vertexCoords) { Polygon polygon; if (_mode == GeometricObject.PolygonMode.Triangular) { polygon = new Triangle(); } else if (_mode == GeometricObject.PolygonMode.Quadratic) { polygon = new Quadrangle(); } else { throw new InvalidObjectMeshException(); } List <Coordinate> edgeCoords = new List <Coordinate>(); foreach (int index in _indices) { edgeCoords.Add(vertexCoords[index]); } polygon.InsertEdgeCoords(edgeCoords); return(polygon); }
private static Rectangle CalcGlobalAABB(Node node) { if (node is PointObject pointObject) { var parent = pointObject.Parent.AsWidget; var pos = pointObject.CalcPositionInSpaceOf(parent) * parent.LocalToWorldTransform; var offset = new Vector2(PointObjectsPresenter.CornerOffset); return(new Rectangle(pos - offset, pos + offset)); } if (node is Widget widget) { var transform = widget.LocalToWorldTransform; var result = new Quadrangle { V1 = Vector2.Zero * transform, V2 = new Vector2(widget.Width, 0) * transform, V3 = widget.Size * transform, V4 = new Vector2(0, widget.Height) * transform }.ToAABB(); foreach (var childNode in widget.Nodes) { var aabb = CalcGlobalAABB(childNode); if (aabb.Width + aabb.Height <= Mathf.ZeroTolerance) { continue; } result = Rectangle.Bounds(result, aabb); } return(result); } return(new Rectangle(Vector2.Zero, Vector2.Zero)); }
/// <summary> /// Funkcja sprawdza czy samolot bedzie mogl trafic rakieta w inny obiekt. /// </summary> /// <param name="plane">Samolot strzelajacy.</param> /// <param name="enemyPlane">Samolot, ktory chemy trafic.</param> /// <returns>Zwraca true jesli moze trafic wrogi samolot; false - w przeciwnym /// przypadku.</returns> /// <author>Michal Ziober</author> public static CollisionDirectionLocation CanHitEnemyPlane(Plane plane, Plane enemyPlane, float tolerance, bool biDirectional) { if (!biDirectional) { if (plane.Direction == Direction.Right && plane.Center.X > enemyPlane.Center.X) { return(CollisionDirectionLocation.NONE); } if (plane.Direction == Direction.Left && plane.Center.X < enemyPlane.Center.X) { return(CollisionDirectionLocation.NONE); } } if (System.Math.Abs(plane.Center.X - enemyPlane.Center.X) < 10 && System.Math.Abs(plane.Center.Y - enemyPlane.Center.Y) < 10) { return(CollisionDirectionLocation.NONE); } if (System.Math.Abs((plane.Center - enemyPlane.Center).EuclidesLength) > ViewRange) { return(CollisionDirectionLocation.NONE); } Quadrangle planeQuad = new Quadrangle(plane.Bounds.Peaks); planeQuad.Move(0, -HeightShift); Line lineA = new Line(planeQuad.Peaks[1], planeQuad.Peaks[2]); for (int i = 0; i < enemyPlane.Bounds.Peaks.Count - 1; i++) { PointD start = enemyPlane.Bounds.Peaks[i]; start += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); PointD finish = enemyPlane.Bounds.Peaks[i + 1]; finish += new PointD(Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f), Math.RangeRandom(-tolerance * 0.5f, -tolerance * 0.5f)); Line lineB = new Line(start, finish); PointD cut = lineA.Intersect(lineB); if (cut == null) { continue; } if ((enemyPlane.Center - cut).EuclidesLength < HitShift) { //ViewHelper.AttachCross(plane.Level.Controller.GetFramework().SceneMgr, cut, 10); //return true; return((plane.Direction == Direction.Right && plane.Center.X > enemyPlane.Center.X || plane.Direction == Direction.Left && plane.Center.X < enemyPlane.Center.X) ? CollisionDirectionLocation.BACKWARD : CollisionDirectionLocation.FORWARD); } } return(CollisionDirectionLocation.NONE); }
/// <summary> /// Konstruktor piecioparametrowy. /// </summary> /// <param name="yBegin">Wysokosc poczatku obiektu.</param> /// <param name="yEnd">Wysokosc konca obiektu.</param> /// <param name="hitBound">Prostokat opisujacy obiekt.</param> /// <param name="type">Typ obiektu.</param> /// <param name="collisionRectangles">Lista prostokatow z ktorymi moga wystapic zderzenia.</param> public ShipTile(float yBegin, float yEnd, float viewXShift, Quadrangle hitBound, int type, List <Quadrangle> collisionRectangles, bool traversable) : base(yBegin, yEnd, viewXShift, hitBound, collisionRectangles) { this.type = type; this.traversable = traversable; sinkComponent = new SinkComponent(this, this); }
/// <summary> /// Funkcja sprawdza czy dany obiekt jest w kolizji /// z innym prostokatem:bomba, rakieta, etc /// </summary> /// <param name="quad">Prostokat z ktorym sprawdzamy kolizje.</param> /// <returns>Jesli kolizja wystapila choc z jednym elementem zwraca true; /// w przeciwnym przypadku zwraca false.</returns> public virtual CollisionType InCollision(Quadrangle quad) { if (this is FortressBunkerTile) { } if (quad == null) { return(CollisionType.None); } if (this.InSimpleCollision(quad.Center)) { return(CollisionType.Altitude); } if (hitBound != null && hitBound.Intersects(quad)) { return(CollisionType.Hitbound); } List <Quadrangle> list = ColisionRectangles; if (list != null) { for (int i = 0; i < list.Count; i++) { if (list[i].Intersects(quad)) { return(CollisionType.CollisionRectagle); } } } return(CollisionType.None); }
IEnumerator <object> Rescale(int controlPointIndex, MouseCursor cursor, List <PointObject> points) { var t = sv.Scene.CalcTransitionToSpaceOf(Document.Current.Container.AsWidget); Document.Current.History.BeginTransaction(); try { Utils.ChangeCursorIfDefault(cursor); initialMousePosition = sv.MousePosition; initialPointsBounds = Utils.CalcAABB(points); while (sv.Input.IsMousePressed()) { Document.Current.History.RevertActiveTransaction(); if (CoreUserPreferences.Instance.AutoKeyframes) { Utils.SetAnimatorAndInitialKeyframeIfNeed(points.Cast <IAnimable>(), nameof(PointObject.Position)); } Utils.ChangeCursorIfDefault(cursor); RescaleHelper( points, controlPointIndex, sv.Input.IsKeyPressed(Key.Shift), sv.Input.IsKeyPressed(Key.Control)); yield return(null); } } finally { sv.Input.ConsumeKey(Key.Mouse0); Document.Current.History.EndTransaction(); } }
IEnumerator <object> DragShared(Quadrangle hull) { var widgets = Document.Current.SelectedNodes().Editable().OfType <Widget>().ToList(); using (Document.Current.History.BeginTransaction()) { while (sv.Input.IsMousePressed()) { Document.Current.History.RollbackTransaction(); var curMousePos = SnapMousePosToSpecialPoints(hull, sv.MousePosition, Vector2.Zero); foreach (var widget in widgets) { var transform = widget.LocalToWorldTransform.CalcInversed(); var newPivot = curMousePos * transform / widget.Size; Core.Operations.SetAnimableProperty.Perform( widget, nameof(Widget.Position), curMousePos * widget.ParentWidget.LocalToWorldTransform.CalcInversed(), CoreUserPreferences.Instance.AutoKeyframes ); Core.Operations.SetAnimableProperty.Perform( widget, nameof(Widget.Pivot), newPivot, CoreUserPreferences.Instance.AutoKeyframes ); } yield return(null); } sv.Input.ConsumeKey(Key.Mouse0); Document.Current.History.CommitTransaction(); } }
public static Quadrangle ExpandAndTranslateToSpaceOf(Quadrangle hull, Widget sourceWidget, Widget destWidget) { var t = sourceWidget.CalcTransitionToSpaceOf(destWidget); var size = sourceWidget.Size; var corners = new Quadrangle(); for (var i = 0; i < 4; i++) { corners[i] = Corners[i] * size * t; hull[i] *= t; } var bounds = new Quadrangle(); for (var i = 0; i < 4; i++) { var next = (i + 1) % 4; var prev = (i + 3) % 4; var dir1 = hull[i] - hull[next]; var dir2 = hull[i] - hull[prev]; if (dir1 + dir2 == Vector2.Zero) { dir1 = corners[i] - corners[next]; dir2 = corners[i] - corners[prev]; } bounds[i] = hull[i] + (dir1.Normalized + dir2.Normalized) * CornerOffset; } return(bounds); }
public void SetCorners(Quadrangle quadrangle) { manualObject.RenderQueueGroup = (byte)RenderQueueGroupID.RENDER_QUEUE_OVERLAY; manualObject.QueryFlags = 0; Vector2 leftBottom = UnitConverter.LogicToWorldUnits(quadrangle.Peaks[0]); Vector2 leftTop = UnitConverter.LogicToWorldUnits(quadrangle.Peaks[1]); Vector2 rightTop = UnitConverter.LogicToWorldUnits(quadrangle.Peaks[2]); Vector2 rightBottom = UnitConverter.LogicToWorldUnits(quadrangle.Peaks[3]); manualObject.Clear(); manualObject.Begin("Misc/BoundingQuadrangle", RenderOperation.OperationTypes.OT_LINE_STRIP); manualObject.Position(leftBottom.x, leftBottom.y, 0); manualObject.TextureCoord(0, 0); manualObject.Position(leftTop.x, leftTop.y, 0); manualObject.TextureCoord(0, 1); manualObject.Position(rightTop.x, rightTop.y, 0); manualObject.TextureCoord(1, 1); manualObject.Position(rightBottom.x, rightBottom.y, 0); manualObject.TextureCoord(0, 1); manualObject.Position(leftBottom.x, leftBottom.y, 0); manualObject.TextureCoord(0, 0); manualObject.End(); AxisAlignedBox box = new AxisAlignedBox(); box.SetInfinite(); manualObject.BoundingBox = box; OnSetCorners(); }
/// <summary> /// Gets the nearest path graph vertex from the specified position. /// </summary> /// <param name="from"></param> /// <returns></returns> public PathGraphVertex FindNearestPathGraphVertex(Vector2 from) { PathGraphVertex res = null; PathGraphVertex fallDownResult = null; float minDistance = float.MaxValue; foreach (GridField field in fields) { foreach (PathGraphVertex vertex in field.PathGraphVertices) { if (fallDownResult == null) { fallDownResult = vertex; } Vector2 way = (from - vertex.Position.PositionInQuarter); float direction = (way.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi; Quadrangle pathObj = Quadrangle.CreateBand(vertex.Position.PositionInQuarter, direction, 0.5f, way.Length()); //Quadrangle pathObj = new Quadrangle(vertex.Position.PositionInQuarter, vertex.Position.PositionInQuarter, from, from); if ((vertex.Position.PositionInQuarter - from).Length() < minDistance && !IsInCollision(pathObj, x => !(x is Human))) { res = vertex; minDistance = (vertex.Position.PositionInQuarter - from).Length(); } } } if (res != null) { return(res); } return(fallDownResult); }
private void IntersectionTestForm_KeyDown(object sender, KeyEventArgs e) { const float angle = Math.PI / 36.0f; PointD rotateCenter = new PointD(200, 300); switch (e.KeyCode) { case Keys.Up: activeQ.Move(0, Step); break; case Keys.Down: activeQ.Move(0, -Step); break; case Keys.Left: activeQ.Move(-Step, 0); break; case Keys.Right: activeQ.Move(Step, 0); break; case Keys.NumPad8: activeQ.Rotate(angle); break; case Keys.NumPad2: activeQ.Rotate(-angle); break; case Keys.B: activeQ = q1; break; case Keys.G: activeQ = q2; break; case Keys.NumPad9: activeQ.Move(Step, Step); break; //case ' ': MessageBox.Show(q1.ToString()); break; default: break; } pictureBox1.Refresh(); if (q1.Intersects(q2)) { Text = "BUM"; } else { Text = ""; } }
/// <summary> /// Konstruktor dwuparametrowy. /// </summary> /// <param name="x">Wspolrzedna startowa x.</param> /// <param name="y">Wspolrzedna startowa y.</param> /// <param name="planeSpeed">Wektor ruchu.</param> /// <param name="level">Referencja do obiektu Level.</param> /// <author>Michal Ziober</author> public Bomb(float x, float y, PointD planeSpeed, Level level, float angle, IObject2D owner) : base(level, angle, owner) { //prostokat opisujacy obiekt. boundRectangle = new Quadrangle(new PointD(x, y - 1), BombWidth, BombHeight); //wektor ruchu. moveVector = new PointD(WidthCoefficient * planeSpeed.X, HeightCoefficient); }
public TextureInPoint( CachedTexture texture, Quadrangle quadrangle ) { this._angel = 0.0f; this._texture = texture; this._quadrangle = quadrangle; this.CalculateBlocks(); this._width = 0.01f; this._heigth = 0.01f; }
public StoragePlane(Level level, AircraftCarrierTile tile, PlaneType type) : base(level, false, type) { this.tile = tile; bounds = new Quadrangle(new PointD(Mathematics.IndexToPosition(tile.TileIndex), level.Carrier.Height), Width, Height); }
IEnumerable <Vector2> GetSpecialPoints(Quadrangle hull) { for (int i = 0; i < 4; i++) { yield return(hull[i]); yield return((hull[i] + hull[(i + 1) % 4]) / 2); } yield return((hull[0] + hull[2]) / 2); }
public Quadrangle GetZoneQuadrangle(string zone_name) { Quadrangle ret = new Quadrangle(csSmartIdEnginePINVOKE.SegmentationResult_GetZoneQuadrangle(swigCPtr, zone_name), false); if (csSmartIdEnginePINVOKE.SWIGPendingException.Pending) { throw csSmartIdEnginePINVOKE.SWIGPendingException.Retrieve(); } return(ret); }
/// <summary> /// Unregisters a new object. /// </summary> /// <param name="obj">The object</param> public void RemoveObject(Quadrangle obj) { objects.Remove(obj); List <GridField> fields = new List <GridField>(obj.SpacePartitioningFields); foreach (GridField field in fields) { field.RemoveObject(obj); } }
/// <summary> /// Publiczny konstruktor czteroparametrowy. /// </summary> /// <param name="yBegin">Wspolrzedna y poczatku instalacji.</param> /// <param name="yEnd">Wspolrzedna y konca instalacji.</param> /// <param name="hitBound">Prostokat opisujacy obiekt.</param> /// <param name="soldierNum">Liczba zolnierzy.</param> /// <param name="type">Typ bunkra.</param> /// <param name="collisionRectangle">Lista prostokatow z ktorymi moga wystapic zderzenia.</param> public EnemyInstallationTile(float yBegin, float yEnd, float viewXShift, Quadrangle hitBound, int soldierNum, int generalNum, int type, List <Quadrangle> collisionRectangle) : base(yBegin, yEnd, viewXShift, hitBound, type, collisionRectangle, true) { Initializing(); soldiersCount = soldierNum; generalsCount = generalNum; maxInfantryCount = generalsCount + soldiersCount; IncrementIntactInstallationCount(); }
/// <summary> /// Konstruktor szescioparametrowy. Tworzy /// nowy bunkier drewniany na planszy. /// </summary> /// <param name="yBegin">Poczatek bunkru.</param> /// <param name="yEnd">Koniec bunkru.</param> /// <param name="hitBound">Prostokat opisujacy bunkier.</param> /// <param name="soldierNum">Liczba zolnierzy.</param> /// <param name="type">Typ bunkru.</param> /// <param name="collisionRectangle">Lista prostokatow z ktorymi moga wystapic zderzenia.</param> public WoodBunkerTile(float yBegin, float yEnd, float viewXShift, Quadrangle hitBound, int soldierNum, int generalNum, int type, List <Quadrangle> collisionRectangle) : base(yBegin, yEnd, viewXShift, hitBound, soldierNum, generalNum, type, collisionRectangle) { //instalacja przy starcie nie jest zniszczona. enemyState = EnemyInstallationState.Intact; //pole razenia Ustawione podczas ustawiania indeksu. horizon = null; currentTime = 0; }
/// <summary> /// Updates the kill task logic. It navigates the holder to the target and waits for him to shoot the target. If the holder has not a usable gun, it leads him to search for a toolbox. It can also lead him to for a healbox if it is needed. /// </summary> /// <param name="gameTime">Game time</param> public override void Update(GameTime gameTime) { if (Holder.SelectedTool is Gun && ((Gun)Holder.SelectedTool).Type.Range < TownQuarter.SquareWidth) { Box nearestToolBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, true); if (nearestToolBox != null) { Holder.AddUrgentTask(new MoveTask(Holder, nearestToolBox.Pivot)); } } int neededHealth = target.Health - (Holder.SelectedTool is Gun ? ((Gun)Holder.SelectedTool).Type.Damage : 0); if (Holder.Health < neededHealth) { Box nearestHealBox = Holder.Position.Quarter.GetNearestBox(Holder.Position, false); if (nearestHealBox != null) { Holder.AddUrgentTask(new MoveTask(Holder, nearestHealBox.Pivot)); } } if (gameTime.TotalGameTime - lastUpdatedWaypoints > RecomputeWaypointsTimeout && (lastTargetQuarter != target.Position.Quarter || target.Position.Quarter == Holder.Position.Quarter)) { lastTargetQuarter = target.Position.Quarter; goStraightToTarget = false; if (Holder.Position.Quarter == target.Position.Quarter) { Vector2 wayVect = (target.Position.PositionInQuarter - Holder.Position.PositionInQuarter); float direction = (wayVect.GetAngle() + 1 * MathHelper.PiOver2) % MathHelper.TwoPi; Quadrangle viewLine = Quadrangle.CreateBand(Holder.Pivot.PositionInQuarter, direction, Holder.Size.X, wayVect.Length()); goStraightToTarget = !Grid.IsInCollision(viewLine, c => !(c is Human)); } if (!goStraightToTarget) { RecomputeWaypoints(Holder.Position, target.Position); } lastUpdatedWaypoints = gameTime.TotalGameTime; } if (goStraightToTarget) { if (Holder.Position.MinimalDistanceTo(target.Position) > TownQuarter.SquareWidth) { Holder.GoThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } else { Holder.TurnThisWay(target.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } } else { base.Update(gameTime); } }
bool KillEnemyReflex(GameTime gameTime) { if (gameTime.TotalGameTime - lastKillEnemyReflexTime > KillEnemyReflexTimeout && tools.Any(x => (x is Gun && x.Usable))) { lastKillEnemyReflexTime = gameTime.TotalGameTime; Human seenEnemy = null; float enemyShotDistance = tools.Max(x => (x is Gun && x.Usable ? ((Gun)x).Type.Range : 0f)); Quadrangle viewCone = GetViewCone(enemyShotDistance); if (lastSeenEnemy != null && viewCone.IsInCollisionWith(lastSeenEnemy)) { //Quadrangle clearViewQuad = new Quadrangle(lastSeenEnemy.PositionInQuarter.XZToVector2(), lastSeenEnemy.PositionInQuarter.XZToVector2(), Pivot.PositionInQuarter, Pivot.PositionInQuarter); //IEnumerable<Quadrangle> inView = from obj in Position.Quarter.SpaceGrid.GetAllCollisions(clearViewQuad) where obj != this && obj != lastSeenEnemy select obj; //if (inView.Any()) //{ //lastSeenEnemy = null; //} //else //{ seenEnemy = lastSeenEnemy; //} } else { lastSeenEnemy = null; } if (gameTime.TotalGameTime - lastTimeSawEnemy >= CheckEnemiesInViewConeTimeout && seenEnemy == null) { IEnumerable <Human> seenEnemies = from obj in Position.Quarter.SpaceGrid.GetAllCollisions(viewCone) where obj is Human && obj != this && enemies.Contains((Human)obj) select obj as Human; if (seenEnemies.Any()) { seenEnemy = seenEnemies.First(); } lastTimeSawEnemy = gameTime.TotalGameTime; } if (seenEnemy != null) { lastSeenEnemy = seenEnemy; selectedToolIndex = tools.FindIndex(x => (x is Gun && ((Gun)x).Type.Range == enemyShotDistance)); float direction = (seenEnemy.PositionInQuarter.XZToVector2() - Position.PositionInQuarter).GetAngle() + 1 * MathHelper.PiOver2; if (!IsAzimuthTooFarFrom(direction, gameTime.ElapsedGameTime.TotalSeconds * RotateAngle)) { DoToolAction(gameTime); } else { GoThisWay(seenEnemy.Position, (float)gameTime.ElapsedGameTime.TotalSeconds); } return(true); } } return(false); }
/// <summary> /// Determines whether a certain area lies within a circle. /// </summary> /// <param name="area">The area to check for collision in entity space.</param> /// <param name="rotation">This is ignored for circles.</param> /// <returns><c>true</c> if <paramref name="area"/> does collide with the circle, <c>false</c>.</returns> public override bool CollisionTest(Quadrangle area, float rotation) { // Empty or negative circles can never intersect if (Radius <= 0) { return(false); } // Shift area to the circle center as the origin return(area.IntersectCircle(Radius)); }
public TilesNode() { yEnd = -1.0f; yStart = -1.0f; variation = 0; hitRectangle = null; rectangle = null; baseName = ""; id = ""; collisionRectangle = new List <Quadrangle>(); }
/// <summary> /// 指定の法線の面の頂点データを作成します。 /// </summary> /// <param name="source">対応する面の VertexSource。</param> /// <param name="normal">面の法線。</param> void InitializeSurface(SurfaceVertexSource source, Vector3 normal) { var quadrangle = new Quadrangle(); float s = Size * 0.5f; var side1 = new Vector3(normal.Y, normal.Z, normal.X); var side2 = Vector3.Cross(normal, side1); quadrangle.Position0 = (normal - side1 - side2) * s; quadrangle.Position1 = (normal - side1 + side2) * s; quadrangle.Position2 = (normal + side1 + side2) * s; quadrangle.Position3 = (normal + side1 - side2) * s; quadrangle.Normal = normal; quadrangle.Make(source); }
/// <summary> /// Performes the bullet releasing in the shoot process /// </summary> /// <param name="gameTime">Game time</param> /// <param name="position">Start position</param> /// <param name="azimuth">Flight direction</param> /// <param name="visualiseBullet">Whether the bullet should be visualised indicator</param> /// <returns>True if the bullet hit something</returns> bool PerformShoot(GameTime gameTime, PositionInTown position, float azimuth, bool visualiseBullet) { const float bulletWidth = 0.02f; //const float startHeight = 0.5f; const float bulletWidthHalf = bulletWidth / 2; bool solveHeight = (Holder is Player); double lookAngle = Holder.LookAngle; //Vector2 quarterPosition = position.PositionInQuarter; float startHeight = Holder.FirstHeadPosition.Y - bulletWidth; Vector2 quarterPosition = position.PositionInQuarter; Vector2 left = quarterPosition.Go(bulletWidthHalf, azimuth - MathHelper.PiOver2); Vector2 right = quarterPosition.Go(bulletWidthHalf, azimuth + MathHelper.PiOver2); Quadrangle bullet = new Quadrangle(right, left, right.Go(type.Range, azimuth), left.Go(type.Range, azimuth)); TownQuarter quarter = position.Quarter; List<Quadrangle> colliders = new List<Quadrangle>(quarter.SpaceGrid.GetAllCollisions(bullet)); colliders.RemoveAll(x => x == Holder); //Half-interval search Stack<RangeF> testedParts = new Stack<RangeF>(); Dictionary<float, float> heights = new Dictionary<float, float>(); testedParts.Push(new RangeF(0, type.Range)); if (solveHeight) { heights.Add(0, startHeight); heights.Add(type.Range, startHeight + type.Range * (float)Math.Tan(lookAngle)); } Quadrangle nearest = null; float distance = type.Range; while (testedParts.Count != 0) { RangeF bulletRangePart = testedParts.Pop(); float h1 = 0f; float h2 = 0f; if (solveHeight) { h1 = heights[bulletRangePart.Begin]; h2 = heights[bulletRangePart.End]; } Quadrangle bulletPart = new Quadrangle( left.Go(bulletRangePart.Begin, azimuth), right.Go(bulletRangePart.Begin, azimuth), left.Go(bulletRangePart.End, azimuth), right.Go(bulletRangePart.End, azimuth)); List<Quadrangle> newColliders = new List<Quadrangle>( colliders.Where( x => (solveHeight && x is SpatialObject && (((SpatialObject)x).Size.Y >= h2 || ((SpatialObject)x).Size.Y >= h2) && (0 <= h1 || 0 <= h2) && x.IsInCollisionWith(bulletPart)) || (!solveHeight && x.IsInCollisionWith(bulletPart)) ) ); if (newColliders.Count != 0) { if (newColliders.Count == 1 || bulletRangePart.Length <= bulletWidthHalf) { nearest = newColliders[0]; distance = bulletRangePart.End; break; } colliders = newColliders; float halfLength = bulletRangePart.Length * 0.5f; float middle = bulletRangePart.Begin + halfLength; testedParts.Push(new RangeF(middle, bulletRangePart.End)); testedParts.Push(new RangeF(bulletRangePart.Begin, middle)); if (solveHeight && halfLength != 0f) { heights.Add(middle, startHeight + middle * (float)Math.Tan(lookAngle)); } } } if (visualiseBullet) { quarter.AddBullet(gameTime, new BulletVisualisation(quarter, quarterPosition, azimuth, distance, startHeight, startHeight + distance * (float)Math.Tan(lookAngle))); } if (nearest != null) { Debug.Write("Shot", nearest.ToString()); nearest.BecomeShoot(gameTime, type.Damage, Holder); return true; } return false; }
/// <summary> /// Solves a collision with the specified object. /// </summary> /// <param name="something">The hit object</param> /// <param name="gameLogicOnly">The simple mode indicator</param> /// <param name="gameTime">Game time</param> public override void Hit(Quadrangle something, bool gameLogicOnly, GameTime gameTime) { if (something is ToolBox) { Hit(something as ToolBox); } else if (something is HealBox) { Hit(something as HealBox); } else { MoveTo(LastPosition, Azimuth); } }
/// <summary> /// Unregisters the specified object. /// </summary> /// <param name="obj">The object</param> public void RemoveObject(Quadrangle obj) { if (!isInCollisionProcessing) { objects.Remove(obj); obj.SpacePartitioningFields.Remove(this); } else { objectsForRemove.Add(obj); } }
void ResolvePositionNormal(ref Quadrangle quadrangle, ref Vector3 normal) { var halfSize = Size * 0.5f; var side1 = new Vector3(normal.Y, normal.Z, normal.X); var side2 = Vector3.Cross(normal, side1); // REFERENCE: 立方体頂点計算アルゴリズムは XNA の Primitive3D サンプル コードより。 quadrangle.Position0 = (normal - side1 - side2) * halfSize; quadrangle.Position1 = (normal - side1 + side2) * halfSize; quadrangle.Position2 = (normal + side1 + side2) * halfSize; quadrangle.Position3 = (normal + side1 - side2) * halfSize; quadrangle.Normal = normal; }
/// <summary> /// VertexSource へ頂点データを設定します。 /// </summary> /// <param name="source">頂点データが設定される VertexSource。</param> public void Make(VertexSource<VertexPositionNormalColor, ushort> source) { EnsureColors(); var quad = new Quadrangle(); for (int i = 0; i < normals.Length; i++) { ResolvePositionNormal(ref quad, ref normals[i]); quad.Color = colors[i]; quad.Make(source); } }
/// <summary> /// Registers an object in this field. /// </summary> /// <param name="obj">The object</param> public void AddObject(Quadrangle obj) { objects.Add(obj); obj.SpacePartitioningFields.Add(this); }
/// <summary> /// Calculates all callision of the specified objects inside this field. /// </summary> /// <param name="obj">The tested object</param> /// <returns>Set of colliding objects from this field</returns> public IEnumerable<Quadrangle> GetCollisions(Quadrangle obj) { isInCollisionProcessing = true; foreach (Quadrangle quad in objects) { if (obj.IsInCollisionWith(quad) && obj != quad) { yield return quad; } } isInCollisionProcessing = false; foreach (Quadrangle rem in objectsForRemove) { RemoveObject(rem); } objectsForRemove.Clear(); }
/// <summary> /// Updates the object logic. Checks availability for humans and let them know about it. /// </summary> /// <param name="gameTime">Game time</param> public virtual void Update(GameTime gameTime) { if (gameTime.TotalGameTime - lastTimeRangeChecked > CheckRangeTimeout) { lastTimeRangeChecked = gameTime.TotalGameTime; Vector2 center = Pivot.PositionInQuarter; Vector2[] corners = new Vector2[] { UpperLeftCorner, UpperRightCorner, LowerLeftCorner, LowerRightCorner }; for (int i = 0; i < corners.Length; i++ ) { Vector2 movement = Vector2.Normalize(corners[i] - center) * actionDistance; corners[i] += movement; } Quadrangle range = new Quadrangle(corners[0], corners[1], corners[2], corners[3]); IEnumerable<Quadrangle> collisions = Position.Quarter.SpaceGrid.GetAllCollisions(range); HashSet<Human> newHumans = new HashSet<Human>(); foreach (Quadrangle collision in collisions) { if (collision is Human) { Human human = ((Human)collision); if (!availibleHumans.Contains(human)) { human.RegisterAvailableAction(this); } newHumans.Add(human); } } availibleHumans.ExceptWith(newHumans); foreach (Human oldHuman in availibleHumans) { oldHuman.UnregisterAvailableAction(this); } availibleHumans = newHumans; } }