Vec2D ProjectPointOnLine(Vec2D p1, Vec2D p2, Double d) { Vec2D r = new Vec2D(0, 0); Double d1, x1, y1, x2, y2, x3, y3; x1 = p1.X; y1 = p1.Y; x2 = p2.X; y2 = p2.Y; d1 = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2)); if ((y2 == y1) && (x2 == x1)) // p1 == p2 is not allowed { return(null); } else { x3 = x1 + ((d * (x2 - x1)) / d1); y3 = y1 + ((d * (y2 - y1)) / d1); r.X = x3; r.Y = y3; return(r); } }
private static double CalculateDistanceToNearestEndpoint(BspSegment segment, double tSegment) { Vec2D endpointVertex = (tSegment < 0.5 ? segment.Start.Struct() : segment.End.Struct()); Vec2D intersectionPoint = segment.FromTime(tSegment); return(endpointVertex.Distance(intersectionPoint)); }
//Vec2D SmallestX(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].X < r.X) // { // r = l[i]; // } // } // return r; //} //Vec2D SmallestY(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].Y < r.Y) // { // r = l[i]; // } // } // return r; //} //Vec2D BiggestY(List<Vec2D> l) //{ // Vec2D r = l[0]; // for (int i = 1; i < l.Count; i++) // { // if (l[i].Y > r.Y) // { // r = l[i]; // } // } // return r; //} //Polygon2D GetPoly2(Vec2D p1, Vec2D p2) //{ // double halfwidth = m_avoidPathWidth / 2; // Polygon2D poly = new Polygon2D(); // List<Vec2D> vertices = new List<Vec2D>(); // Vec2D v1 = GetPerpendicularPoint(p1, p2, -1* halfwidth); // Vec2D v2 = GetPerpendicularPoint(p1, p2, 1 * halfwidth); // Vec2D v3 = GetPerpendicularPoint(p2, p1, 1 * halfwidth); // Vec2D v4 = GetPerpendicularPoint(p2, p1, -1 * halfwidth); // if (v1 == null || v2 == null || v3 == null || v4 == null) // { // return null; // } // else // { // vertices.Add(v1); // vertices.Add(v2); // vertices.Add(v3); // vertices.Add(v4); // Vec2D first = SmallestX(vertices); // vertices.Remove(first); // Vec2D second = SmallestX(vertices); // vertices.Remove(second); // Vec2D third; // if (second.Y > first.Y) // { // third = BiggestY(vertices); // vertices.Remove(third); // } // else // { // third = SmallestY(vertices); // vertices.Remove(third); // } // Vec2D fourth = vertices[0]; // poly.AddVertex(first); // poly.AddVertex(second); // poly.AddVertex(third); // poly.AddVertex(fourth); // return poly; // } //} //Vec2D GetPerpendicularPoint(Vec2D p1, Vec2D p2, double d) //{ // Vec2D p3 = new Vec2D(0, 0); // p3.X = p2.X + 1; // double m = -1 * ((p2.Y - p1.Y) / (p2.X - p1.X)); // double b = p2.Y + ((p2.Y - p1.Y) / (p2.X - p1.X)); // p3.Y = (m * p3.X) + b; // return ProjectPointOnLine(p2, p3, d); //} Polygon2D GetPoly(Vec2D p1, Vec2D p2) { double halfwidth = m_avoidPathWidth / 2; Polygon2D poly = new Polygon2D(); double dx = p2.X - p1.X >= 0 ? halfwidth : halfwidth * -1; double dy = p2.Y - p1.Y >= 0 ? halfwidth : halfwidth * -1; if (Math.Abs(p2.X - p1.X) > Math.Abs(p2.Y - p1.Y)) { poly.AddVertex(new Vec2D(p1.X, p1.Y - halfwidth)); poly.AddVertex(new Vec2D(p1.X, p1.Y + halfwidth)); poly.AddVertex(new Vec2D(p2.X + dx, p2.Y + halfwidth)); poly.AddVertex(new Vec2D(p2.X + dx, p2.Y - halfwidth)); return(poly); } else { poly.AddVertex(new Vec2D(p1.X - halfwidth, p1.Y)); poly.AddVertex(new Vec2D(p1.X + halfwidth, p1.Y)); poly.AddVertex(new Vec2D(p2.X + halfwidth, p2.Y + dy)); poly.AddVertex(new Vec2D(p2.X - halfwidth, p2.Y + dy)); return(poly); } }
public override void Update() { if (InputWinform.Instance.GetKeyDown(Keys.A)) { Vec2D point = gameObject.transform.position; point.X -= MoveSpeed * GameEngine.Instance.DeltaTime; if (point.X - imageWidthHlaf < 0) { point.X = imageWidthHlaf; } gameObject.transform.position = point; } if (InputWinform.Instance.GetKeyDown(Keys.D)) { Vec2D point = gameObject.transform.position; point.X += MoveSpeed * GameEngine.Instance.DeltaTime; if (point.X + imageWidthHlaf > MaxWidth) { point.X = MaxWidth - imageWidthHlaf; } gameObject.transform.position = point; } }
protected override Vec4D CalculateMotionData4D(Particle particle) { //normal displacement var cr = particle.CollisionRadius * particle.Scale; var r = Vec2D.GetFromPool(particle.X - X, particle.Y - Y); //no collision detected var len = r.Length - cr; if (len > Radius) { Vec2D.RecycleToPool(r); return(null); } //collision detected r.Length = Radius + cr; var v = Vec2D.GetFromPool(particle.Vx, particle.Vy); v.ProjectThis(r); var factor = 1 + Bounce; Vec2D.RecycleToPool(r); Vec2D.RecycleToPool(v); return(Vec4D.GetFromPool(X + r.X, Y + r.Y, (particle.Vx - v.X * factor) * Slipperiness, (particle.Vy - v.Y * factor) * Slipperiness)); }
public T_Move SetToInterceptCourse(T_Move move, T_Reveal reveal, Dictionary <T_Move, T_Reveal> merchantsDict) { //Pick the closest merchant, either newly revealed or existing. double distance = 1000000000000000; T_Move closestKey = null; Vec2D location = new Vec2D(GetLocation(move, reveal)); foreach (T_Move key in merchantsDict.Keys) { double thisDistance = new Vec2D(location).ScalerDistanceTo(new Vec2D(GetLocation(key, merchantsDict[key]))); if (thisDistance < distance) { closestKey = key; distance = thisDistance; } } double merchantSpeed = closestKey.Throttle * GetMaxSpeed(closestKey); Vec2D merchantStart = new Vec2D(GetLocation(closestKey, merchantsDict[closestKey])); Vec2D merchantDestination = new Vec2D((LocationValue)closestKey.Location.Item); Vec2D interceptPoint = GetInterceptPoint(merchantStart, merchantDestination, merchantSpeed, location, GetMaxSpeed(move)); move.Location = new T_Location(); move.Location.Item = interceptPoint.ToLocationValue(); Console.WriteLine("setting pirate " + move.ID + " on intercept course to merchant " + closestKey.ID); return(move); }
//isPirate here refers to the objects we are trying to find, e.g. isPirate = true means find pirates private List <SeamateAdapter.DDD.DDDAdapter.SeamateObject> findObjectsInPlay(LocationValue nearby, PolygonValue pirateEntryRegion, T_Groupings grouping, bool isPirate) { List <DDDAdapter.SeamateObject> vessels = new List <DDDAdapter.SeamateObject>(); foreach (DDDAdapter.SeamateObject vessel in ddd.GetAllRevealedSeaVessels()) { if (isPirate && vessel.Owner == "Pirate DM" || !isPirate && vessel.Owner == "Merchant DM") { } else { continue; } double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(nearby)); bool inSameEntryRegionAsPirate = false; if (pirateEntryRegion != null) { inSameEntryRegionAsPirate = Polygon2D.IsPointInside(new Polygon2D(pirateEntryRegion), new Vec2D(vessel.Location)); } if (grouping == T_Groupings.One && distance < oneGroupingDistance && !inSameEntryRegionAsPirate) { vessels.Add(vessel); } else if (grouping == T_Groupings.Two && distance > twoGroupingDistance && !inSameEntryRegionAsPirate) { vessels.Add(vessel); } } return(vessels); }
/// <summary> /// Determines whether a merchant is within grouping constraints of previously chosen pirates. /// </summary> /// <param name="vessel">Merchant</param> /// <returns>Boolean</returns> private bool MatchesGroupingConstraints(DDDAdapter.SeamateObject vessel) { if (vessel.Intent != "") { return(false); } if (grouping == T_Groupings.One) { foreach (T_Move key in dict.Keys) { Vec2D otherVesselLocation = new Vec2D(GetLocation(key, dict[key])); double distance = new Vec2D(vessel.Location).ScalerDistanceTo(otherVesselLocation); if (distance > oneGroupingDistance) { return(false); } } return(true); } else { return(true); } }
/// <summary> /// Returns a boolean value expressing whether or not a new vessel can be added to an existing group while fulfilling /// grouping constraints. /// One grouping: Every item in the group must be within the one-grouping parameter of each other. /// Two grouping: At least one pair in the group must be separated by the two-grouping parameter. /// </summary> /// <param name="oneOrTwo">Must be "One" or "Two" for a one- or two-grouping</param> /// <param name="newVessel">Vessel to be added to the group</param> /// <param name="otherVessels">Existing group of vessels</param> /// <returns></returns> private bool MatchesGroupingCriteria(T_Groupings grouping, DDDAdapter.SeamateObject newVessel, List <DDDAdapter.SeamateObject> otherVessels) { if (otherVessels.Contains(newVessel)) { return(false); } if (grouping == T_Groupings.One) { foreach (DDDAdapter.SeamateObject vessel in otherVessels) { double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(newVessel.Location)); if (distance > oneGroupingDistance) { return(false); } } return(true); } else { foreach (DDDAdapter.SeamateObject vessel in otherVessels) { double distance = new Vec2D(vessel.Location).ScalerDistanceTo(new Vec2D(newVessel.Location)); if (distance > twoGroupingDistance) { return(true); } } return(false); } }
public Vec2D GetRandomPointInZones() { Vec2D md2D = null; int numZones = Zones.Count; if (numZones > 1) { float sumArea = 0; List <float> areas = new List <float>(); for (int i = 0; i < numZones; i++) { sumArea += Zones[i].GetArea(); areas.Add(sumArea); } float position = (float)Rng.NextDouble() * sumArea; for (int i = 0; i < areas.Count; i++) { if (position <= areas[i]) { md2D = Zones[i].GetPoint(); break; } } } else if (numZones == 1) { md2D = Zones[0].GetPoint(); } return(md2D); // returns null if there are no zones }
public void OperatorOverloadMinus() { Vec2D point = new Vec2D(4f, 3f) - new Vec2D(1f, 2f); Assert.That(point.x, Is.InRange <float>(3f - EPSILON, 3f + EPSILON)); Assert.That(point.y, Is.InRange <float>(1f - EPSILON, 1f + EPSILON)); }
public void OperatorOverloadPlus() { Vec2D point = new Vec2D(1f, 2f) + new Vec2D(3f, 4f); Assert.That(point.x, Is.InRange <float>(4f - EPSILON, 4f + EPSILON)); Assert.That(point.y, Is.InRange <float>(6f - EPSILON, 6f + EPSILON)); }
public void ConstructorParameterless() { Vec2D point = new Vec2D(); Assert.That(point.x, Is.EqualTo(0f)); Assert.That(point.y, Is.EqualTo(0f)); }
/// <summary> /// Makes a point which is in the closest entry region to the group of pirates, /// TODO: but not in the same entry region as any of them. /// </summary> /// <param name="pirates">The move events representing pirates</param> /// <param name="entryRegions">All entry regions</param> /// <returns>A random point in the closest entry region to the group of pirates</returns> private Vec2D GetPointInClosestEntryRegion(Dictionary <T_Move, T_Reveal> pirates, List <PolygonValue> entryRegions) { Vec2D point = new Vec2D(0, 0); double closestDistance = 100000000; PolygonValue closestRegion = null; Shuffle(entryRegions); T_Move randomPirate = pirates.Keys.ToList().ElementAt(0); LocationValue location = GetLocation(randomPirate, pirates[randomPirate]); foreach (PolygonValue entryRegion in entryRegions) { Polygon2D entry2D = new Polygon2D(entryRegion); double distance = Polygon2D.ScalarDistanceToPolygon(entry2D, new Vec2D(location)); if (distance < oneGroupingDistance) { point = entry2D.PointInside(); break; } else { if (distance < closestDistance) { closestDistance = distance; closestRegion = entryRegion; } } } if (point == null) { point = new Polygon2D(closestRegion).PointInside(); } return(point); }
/// <summary> /// Returns a list of entry regions in which new pirates can be added while satisfying grouping constraints, given a group of existing pirates. /// </summary> /// <param name="grouping">Grouping constraints</param> /// <param name="group">Group of existing pirates</param> /// <param name="entryRegions">All avilable entry regions</param> /// <returns></returns> private List <PolygonValue> GetMatchingEntryRegions(T_Groupings grouping, List <DDDAdapter.SeamateObject> group, List <PolygonValue> entryRegions) { List <PolygonValue> matchingEntryRegions = new List <PolygonValue>(); //One grouping: matching entry regions must be within certain distance of every individual vessel in group if (grouping == T_Groupings.One) { foreach (PolygonValue region in entryRegions) { Vec2D regionPoint = new Vec2D(region.points.ElementAt(0).X, region.points.ElementAt(0).Y); bool matching = true; foreach (DDDAdapter.SeamateObject vessel in group) { Vec2D vesselPoint = new Vec2D(vessel.Location); if (vesselPoint.ScalerDistanceTo(regionPoint) > oneGroupingDistance) { matching = false; break; } } if (matching) { matchingEntryRegions.Add(region); } } return(matchingEntryRegions); } //Two grouping: any entry region will do, the existing group satisfies constraint else { return(entryRegions); } }
private static List <SubsectorEdge> CreateSubsectorEdges(ConvexTraversal convexTraversal, Rotation rotation) { List <ConvexTraversalPoint> traversal = convexTraversal.Traversal; Debug.Assert(traversal.Count >= 3, "Traversal must yield at least a triangle in size"); List <SubsectorEdge> subsectorEdges = new List <SubsectorEdge>(); ConvexTraversalPoint firstTraversal = traversal.First(); Vec2D startPoint = firstTraversal.Vertex; foreach (ConvexTraversalPoint traversalPoint in traversal) { BspSegment segment = traversalPoint.Segment; Vec2D endingPoint = segment.Opposite(traversalPoint.Endpoint).Struct(); bool traversedFrontSide = CheckIfTraversedFrontSide(traversalPoint, rotation); SubsectorEdge edge = new SubsectorEdge(startPoint, endingPoint, segment.Line.Value, traversedFrontSide); subsectorEdges.Add(edge); Debug.Assert(startPoint != endingPoint, "Traversal produced the wrong endpoint indices"); startPoint = endingPoint; } Debug.Assert(subsectorEdges.Count == traversal.Count, "Added too many subsector edges in traversal"); return(subsectorEdges); }
/// <summary> /// Creates a subsector edge from some geometric data and for some /// side. /// </summary> /// <param name="start">The starting point.</param> /// <param name="end">The ending point.</param> /// <param name="line">The line this is on top of, or null if this is /// a miniseg.</param> /// <param name="front">True if this is on the front side, false if it /// is the back. This value is not used if this is a miniseg. This /// must never be false for a one sided line.</param> public SubsectorEdge(Vec2D start, Vec2D end, IBspUsableLine line = null, bool front = true) { Start = start; End = end; IsFront = front; Line = line; }
// void Start() public void Load() { // マップ読み込み TMXLoader tmx = new TMXLoader(); tmx.Load("Levels/map"); // 経路レイヤーを取得 Layer2D lPath = tmx.GetLayer("path"); // 開始地点を検索 Vec2D pos = lPath.Search(CHIP_PATH_START); // 座標リストを作成 _path = new List <Vec2D>(); // 開始座標を座標リストに登録 _path.Add(new Vec2D(pos.X, pos.Y)); // 通路をふさぐ lPath.Set(pos.X, pos.Y, CHIP_NONE); // 座標リスト作成 CreatePath(lPath, pos.X, pos.Y, _path); // コリジョンレイヤーを取得する _lCollision = tmx.GetLayer("collision"); }
private void TimeTick(SimulationEvent e) { foreach (StateDB.ActiveRegion region in StateDB.dynamicRegions.Values) { if (region.linkedObject == "") { continue; //don't draw unlinked regions } SimulationObjectProxy obProx = objectProxies[region.linkedObject]; //Calculate new absolute poly for region and send ViewPro event LocationValue lvLoc = (LocationValue)obProx["Location"].GetDataValue(); Vec2D loc = new Vec2D(lvLoc); if (!lvLoc.exists) { return; //possible that the tractor object doesn't exist, so don't show it. } Polygon3D absolutePoly = GetAbsolutePolygon(loc, region.poly.Footprint); absolutePoly.TopZ = region.poly.TopZ; absolutePoly.BottomZ = region.poly.BottomZ; region.referencePoint = loc; region.currentAbsolutePolygon = absolutePoly; this.SendViewProActiveRegionUpdate(region.id, region.isVisible, region.displayColor, absolutePoly); } }
private void Reverse() { Vec2D temp = Start; Start = End; End = temp; }
/// 次の移動先に進める protected void MoveNext() { if (_pathIdx >= _path.Count) { // ゴールにたどりついた _tSpeed = 100.0f; if (X < 0) { Global.Damage(); } else { Global.Damage2(); } //自爆する Vanish(); return; } // ⑧移動先を移動元にコピーする _prev.Copy(_next); // ⑦チップ座標を取り出す Vec2D v = _path[_pathIdx]; _next.x = Field.ToWorldX(v.X); _next.y = Field.ToWorldY(v.Y); // パス番号を進める _pathIdx++; }
public void ConstructorXZ() { Vec2D point = new Vec2D(1f, 2f); Assert.That(point.x, Is.EqualTo(1f)); Assert.That(point.y, Is.EqualTo(2f)); }
public override void Update() { Vec2D nextPoint = gameObject.transform.position; if (ScrollX) { if (XAddNegative) { nextPoint.X -= Speed * GameEngine.Instance.DeltaTime; } else { nextPoint.X += Speed * GameEngine.Instance.DeltaTime; } } if (ScrollY) { if (YAddNegative) { nextPoint.Y -= Speed * GameEngine.Instance.DeltaTime; } else { nextPoint.Y += Speed * GameEngine.Instance.DeltaTime; } } gameObject.transform.position = nextPoint; }
public static Vec2D Normalize(Vec2D v) { var result = v; result.Normalize(); return(result); }
/// <summary> /// Gets the time the point would have on the segment. This does not /// need to be between the [0, 1] range. /// </summary> /// <remarks> /// If the point is not on the segment, then the result will be wrong. /// A corollary to this is that `Start + t*Delta = point`. /// </remarks> /// <param name="point">The point to get the time for.</param> /// <returns>The time the point is on this segment.</returns> public double ToTime(Vec2D point) { if (!Delta.X.ApproxZero()) { return((point.X - Start.X) * DeltaInverse.X); } return((point.Y - Start.Y) * DeltaInverse.Y); }
const float EPSILON = 0.001f; // Intentionally agressive. bool FuzzyEquals(Vec2D a, Vec2D b) { float a0 = a[0], a1 = a[1]; float b0 = b[0], b1 = b[1]; return(Math.Abs(a0 - b0) <= EPSILON * Math.Max(1.0f, Math.Max(Math.Abs(a0), Math.Abs(b0))) && Math.Abs(a1 - b1) <= EPSILON * Math.Max(1.0f, Math.Max(Math.Abs(a1), Math.Abs(b1)))); }
protected Vec2D GetInterceptPoint(Vec2D targetStart, Vec2D targetEnd, double targetSpeed, Vec2D start, double speed) { Vec2D D_o = start.Add(targetStart.Multiply(-1)); //Vector from vessel to target start //Vec2D D_o = targetStart.Add(start.Multiply(-1)); //Vector from vessel to target start double d_o = (Math.Sqrt(Math.Pow(D_o.X, 2) + Math.Pow(D_o.Y, 2))); Vec2D V_m = targetEnd.Add(targetStart.Multiply(-1)); Vec2D unitVectorTarget = new Vec2D(V_m); unitVectorTarget.Normalize(); V_m = unitVectorTarget.Multiply(targetSpeed);//Vector target velocity double v_m = targetSpeed; double targetEndToStartDistance = targetEnd.ScalerDistanceTo(targetStart); double v_p = speed; Vec2D P = start; Vec2D M = targetStart; double cos_B = (D_o.X * V_m.X + D_o.Y * V_m.Y) / (d_o * v_m); double a = (Math.Pow((v_p / v_m), 2) - 1); double b = 2 * (Math.Sqrt(Math.Pow(D_o.X, 2) + Math.Pow(D_o.Y, 2))) * cos_B; double c = -1 * Math.Pow(d_o, 2); double x1 = (-b + Math.Sqrt(Math.Pow(b, 2) - 4 * a * c)) / (2 * a); double x2 = (-b - Math.Sqrt(Math.Pow(b, 2) - 4 * a * c)) / (2 * a); double interceptDistance; if (double.IsNaN(x1) && !double.IsNaN(x2)) { interceptDistance = x2; } else if (double.IsNaN(x2) && !double.IsNaN(x1)) { interceptDistance = x1; } else if (double.IsNaN(x1) && double.IsNaN(x2)) { interceptDistance = targetEndToStartDistance + 100; } else if (x1 > 0 && x2 > 0) { interceptDistance = Math.Min(x1, x2); } else { interceptDistance = Math.Max(x1, x2); } Vec2D interceptPoint; if ((interceptDistance > targetEndToStartDistance)) //vessel can't catch target in the length of the move { interceptPoint = targetEnd; } else { interceptPoint = unitVectorTarget.Multiply(interceptDistance).Add(targetStart); } return(interceptPoint); }
public void Length() { Vec2D point = new Vec2D(2, 2); float length = point.Length(); float expected = (float)(2 * Math.Sqrt(2)); Assert.That(length, Is.InRange <float>(expected - EPSILON, expected + EPSILON)); }
private void TimeTick(SimulationEvent e) { //update time if (((IntegerValue)e["Time"]).value % 1000 == 0) { time = ((IntegerValue)e["Time"]).value / 1000; // time is in ms, we want seconds } /* * "Time" is an attribute of all events. The SimulationModel.xml file lists all of the top-level attributes for each event. * Certain events have an additional "Attribute" attribute, which contains a key-value pair collection of additional attributes. * See RevealObject for an example of this. */ if (((IntegerValue)e["Time"]).value == 1000) { InitializeAllScores(); } SimulationObjectProxy obProx; foreach (string id in objectProxies.Keys) { obProx = objectProxies[id]; bool isInSealane = false; bool movingTowardsPort = false; StringListValue slv = obProx["InActiveRegions"].GetDataValue() as StringListValue; LocationValue dest = obProx["DestinationLocation"].GetDataValue() as LocationValue; if (dest.exists) { Vec2D destVec = new Vec2D(dest); Polygon2D p; foreach (Aptima.Asim.DDD.CommonComponents.SimulatorTools.StateDB.ActiveRegion a in StateDB.activeRegions.Values) { if (!a.id.Contains("Entry-")) { continue; } p = new Polygon2D(); p = a.poly.Footprint; if (Aptima.Asim.DDD.CommonComponents.SimMathTools.Polygon2D.IsPointInside(p, destVec)) { movingTowardsPort = true; } } } if (slv.strings.Count > 0) { isInSealane = true; } obProx["IsInSeaLane"].SetDataValue(DataValueFactory.BuildBoolean(isInSealane)); obProx["IsGoingTowardsPort"].SetDataValue(DataValueFactory.BuildBoolean(movingTowardsPort)); } }
public override void Update() { if (gameObject.transform.position.Y - spriteHeight / 2 >= spriteHeight) { Vec2D point = gameObject.transform.position; point.Y -= spriteHeight * 2; gameObject.transform.position = point; } }