private static void CalculateCrowdingDistance(IGrouping <int, Individual> singleRank) { // As we only have two objectives, ordering individuals along one front allows us to make assumptions // about the locations of the neighbouring individuals in the array. var orderedIndividuals = singleRank.Select(i => i).OrderBy(i => i.NormalizedDistanceFitness).ToArray(); var individualsInFront = orderedIndividuals.Count(); for (int i = 0; i < individualsInFront; i++) { // If we are at the start or end of a front, it should have infinite crowding distance if (i == 0 || i == individualsInFront - 1) { orderedIndividuals[i].CrowdingDistance = double.PositiveInfinity; } else { // Grab a reference to each individual to make the next section a bit cleaner. var current = orderedIndividuals[i]; var left = orderedIndividuals[i - 1]; var right = orderedIndividuals[i + 1]; // Get the positions on the 2D fitness graph, where time is our X axis and distance is our Y. var currentPosition = new Vector2f(current.NormalizedTimeFitness, current.NormalizedDistanceFitness); var leftPosition = new Vector2f(left.NormalizedTimeFitness, left.NormalizedDistanceFitness); var rightPosition = new Vector2f(right.NormalizedTimeFitness, right.NormalizedDistanceFitness); // Calculate the distance to the neighbourn on each side var distanceLeft = currentPosition.Distance(leftPosition); var distanceRight = currentPosition.Distance(rightPosition); // Set the crowding distance for the current individual orderedIndividuals[i].CrowdingDistance = Math.Pow(distanceLeft + distanceRight, 2); } } }
private void UpdateCreate(Vector2f pos) { if (Input.GetMouseButtonDown(0)) { complexPairs.Clear(); complexPairs.Add(pos); } if (createType == CreateType.Slice) { if (Input.GetMouseButton(0)) { if (complexPairs.Count == 0 || (Vector2f.Distance(pos, complexPairs.Last()) > minVertsDistance)) { complexPairs.Add(pos); } mouseDown = true; } if (mouseDown == true && Input.GetMouseButton(0) == false) { mouseDown = false; CreatorSlice(complexPairs); } } else { mouseDown = true; if (Input.GetMouseButtonDown(0)) { PolygonCreator(pos); } } }
private void UpdateComplex(Vector2f pos) { if (Input.GetMouseButtonDown(0)) { complexPairs.Clear(); complexPairs.Add(pos); } if (Input.GetMouseButton(0)) { if (complexPairs.Count == 0 || (Vector2f.Distance(pos, complexPairs.Last()) > minVertsDistance)) { complexPairs.Add(pos); } mouseDown = true; } if (mouseDown == true && Input.GetMouseButton(0) == false) { mouseDown = false; Slicer2D.complexSliceType = complexSliceType; ComplexSlice(complexPairs); complexEvents.Add(complexPairs); } }
/// <summary> /// Arc length of curve via intergration. /// </summary> public float Length(int steps, float tmax = 1.0f) { if (tmax <= 0) { return(0); } if (tmax > 1) { tmax = 1; } if (Degree == 1) { return(Vector2f.Distance(Control[0], Control[1]) * tmax); } else { steps = Math.Max(steps, 2); float len = 0; Vector2f previous = Position(0); for (int i = 1; i < steps; i++) { float t = i / (steps - 1.0f) * tmax; Vector2f p = Position(t); len += Vector2f.Distance(previous, p); previous = p; } return(len); } }
private void UpdateComplex(Vector2f pos) { if (Input.GetMouseButtonDown(0)) { complexPairs.Clear(); complexPairs.Add(pos); } if (Input.GetMouseButton(0)) { Vector2f posMove = new Vector2f(complexPairs.Last()); while ((Vector2f.Distance(posMove, pos) > minVertsDistance)) { float direction = Vector2f.Atan2(pos, posMove); posMove.Push(direction, minVertsDistance); complexPairs.Add(new Vector2f(posMove)); } mouseDown = true; } if (mouseDown == true && Input.GetMouseButton(0) == false) { mouseDown = false; Slicer2D.complexSliceType = complexSliceType; ComplexSlice(complexPairs); complexEvents.Add(complexPairs); } }
void Start() { Vector2f position = new Vector2f(anchorBody.transform.position); GameObject prev = anchorBody; int ropeId = 1; GameObject gObject = null; while (Vector2f.Distance(position, new Vector2f(connectedBody.transform.position)) > .5f) { float direction = Vector2f.Atan2(new Vector2f(connectedBody.transform.position), position); gObject = new GameObject(); gObject.AddComponent <HingeJoint2D>().connectedBody = prev.GetComponent <Rigidbody2D>(); gObject.transform.parent = transform; gObject.transform.position = position.Get(); gObject.name = "Rope " + ropeId; gObject.AddComponent <JointRenderer2D> ().color = color; gObject.AddComponent <CircleCollider2D> ().radius = .25f; nodes.Add(gObject); position.Push(direction, .5f); prev = gObject; ropeId++; } if (gameObject != null) { gObject.AddComponent <HingeJoint2D>().connectedBody = connectedBody.GetComponent <Rigidbody2D>(); } }
private static bool RayIntersectsSegment(Vector2f p, Vector2f n, Vector2f a, Vector2f b, out float t) { t = 0; float dx = a.x - p.x; float dy = a.y - p.y; float len = Vector2f.Distance(a, b); if (FMath.IsZero(len)) { return(false); } Vector2f n1; n1.x = (b.x - a.x) / len; n1.y = (b.y - a.y) / len; float det = n1.x * n.y - n1.y * n.x; if (FMath.IsZero(det)) { return(false); } float s = (dy * n1.x - dx * n1.y) / det; t = (dy * n.x - dx * n.y) / det; t /= len; return(s >= 0 && t >= 0 && t <= 1.0f); }
private void AddChunk(int x, int z) { HeightInfo hi = HmWithCoords(x, z); if (hi == null) { Vector2f vec = new Vector2f(x, z); if (vec.Distance(this.v2cp) < maxDist) { TerrainChunkNode hmtc = CreateNewChunk(physicsWorld, this, x, z, scale, chunkSize, null); heightmaps.Add(hi = new HeightInfo(this, vec, hmtc)); hi.chunk.Create(); ApplyTerrainMaterial(hmtc); hi.chunk.SetLocalTranslation(new Vector3f(x * (chunkSize - 1) * scale.x, 0, z * (chunkSize - 1) * scale.z)); hi.midpoint = new Vector2f(hi.chunk.GetLocalTranslation().x - ((chunkSize - 1) * scale.x / 2), hi.chunk.GetLocalTranslation().z - (chunkSize - 1) * scale.z / 2); Vector2f[] neighbors = GetNeighbors(hi); hi.neighbors = neighbors; rootNode.AddChild(hi.chunk); hi.pageState = PageState.Loaded; } } else { } }
protected override void OnCollisionEnter2D(Collision2D collision) { if (collision.contacts.Any(contact => Vector2f.Distance(contact.normal, this.AllowedDirection.ToUnitVector()) < 0.001f)) { _gameObjectsOnTop.Add(collision.gameObject); } }
public static bool RayIntersectsSegment(Ray2f ray, Segment2f seg, out float s, out float t) { s = t = 0; float dx = seg.A.x - ray.Position.x; float dy = seg.A.y - ray.Position.y; float len = Vector2f.Distance(seg.A, seg.B); if (FMath.IsZero(len)) { return(false); } Vector2f n1; n1.x = (seg.B.x - seg.A.x) / len; n1.y = (seg.B.y - seg.A.y) / len; float det = n1.x * ray.Direction.y - n1.y * ray.Direction.x; if (FMath.IsZero(det)) { return(false); } s = (dy * n1.x - dx * n1.y) / det; t = (dy * ray.Direction.x - dx * ray.Direction.y) / det; t /= len; return(s > 0 && t > 0 && t < 1.0f); }
public void LateUpdate() { complexEvents.Clear(); // Checking mouse press and release events to get linear slices based on input Vector2f pos = new Vector2f(Camera.main.ScreenToWorldPoint(Input.mousePosition)); if (Input.GetMouseButtonDown(0)) { complexPairs.Clear(); complexPairs.Add(pos); } if (Input.GetMouseButton(0)) { if (complexPairs.Count == 0 || (Vector2f.Distance(pos, complexPairs.Last()) > minVertsDistance)) { complexPairs.Add(pos); } mouseDown = true; } if (mouseDown == true && Input.GetMouseButton(0) == false) { mouseDown = false; Slicer2D.complexSliceType = complexSliceType; ComplexSlice(complexPairs); complexEvents.Add(complexPairs); } }
/// <summary> /// Return a sorted list by distance to a given 2D point reference /// </summary> static public List <Vector2f> GetListSortedToPoint(List <Vector2f> pointsList, Vector2f point) { List <Vector2f> resultList = new List <Vector2f>(); List <Vector2f> listCopy = new List <Vector2f> (pointsList); while (listCopy.Count > 0) { float dist = 1e+10f; Vector2f obj = null; foreach (Vector2f p in listCopy) { float d = Vector2f.Distance(point, p); if (d < dist) { obj = p; dist = d; } } if (obj != null) { resultList.Add(obj); listCopy.Remove(obj); } } return(resultList); }
public void Distance() { Vector2f a = new Vector2f(1, 1); Vector2f b = new Vector2f(2, 2); float len = (float)Math.Sqrt(2); Assert.IsTrue(NearlyEqual(len, Vector2f.Distance(a, b))); }
public bool IsTouching(IsoTriangle <T> other, out Vector2f touchPoint, float epsilon = 0.001f) { //DEBUG (sanity check) if (center.Distance(other.center) > Circumradius + other.Circumradius) { touchPoint = Vector2f.One * 100f; return(false); } //END DBUG IsoTriangle <T> larger, smaller; if (other.dims.x < dims.x) { smaller = other; larger = this; } else { smaller = this; larger = other; } var _border = smaller.Border(); float smallestMag = float.MaxValue; touchPoint = _border[0]; for (int i = 0; i < 3; ++i) { // is touching if a slightly nudged point of other // is inside this tri var dif = larger.center - _border[i]; if (dif.LengthSquared < smallestMag) { smallestMag = dif.LengthSquared; touchPoint = _border[i]; } //if(dif.LengthSquared < epsilon) //{ // touchPoint = _border[i]; // return true; //} var touch = _border[i] + dif * epsilon; // -Mathf.Min(other.dims.x, dims.x) / 4f; if (larger.Contains(touch)) { touchPoint = touch; return(true); } } return(false); }
static private Slice2D SliceWithTwoHoles(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice) { Slice2D result = Slice2D.Create(); Polygon polyA = new Polygon(); Polygon polyB = new Polygon(polygon.pointsList); Polygon holeA = polygon.PointInHole(slice.First()); Polygon holeB = polygon.PointInHole(slice.Last()); if (holeA == null || holeB == null) { Debug.LogError("Slicer2D: ERROR Split"); // Shouldn't really happen return(result); } List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(holeA.pointsList, slice); List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(holeB.pointsList, slice); polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon poly in polygon.holesList) { if (poly != holeA && poly != holeB) { polyB.AddHole(poly); } } polyB.AddHole(polyA); result.AddPolygon(polyB); return(result); }
public override Capture UpdateCapture(InputState input, CaptureData data) { // if we already picked a behavior, let it handle things if (inBehavior != null) { Capture result = inBehavior.UpdateCapture(input, data); if (result.state == CaptureState.End) { inBehavior = null; } return(result); } // if we released button, and we are here, we must not have picked yet, so // do full click behavior if (ButtonReleasedF(input)) { Capture begin = ClickBehavior.BeginCapture(input, data.which); if (begin.state == CaptureState.Begin) { Capture update = ClickBehavior.UpdateCapture(input, data); if (update.state != CaptureState.End) { DebugUtil.Log(2, "MouseClickDragSuperBehavior.UpdateCapture: ClickBehavior did not return End"); return(Capture.End); } return(update); } } float fDelta = mouseDownPos.Distance(input.vMousePosition2D); if (fDelta > DragTolerance) { inBehavior = DragBehavior; Capture begin = inBehavior.BeginCapture(input, data.which); if (begin.state == CaptureState.Begin) { Capture update = inBehavior.UpdateCapture(input, data); return(update); } else { return(Capture.End); } } // haven't decided yet, carry on return(Capture.Continue); }
// Not finished - still has some artifacts public static void PreparePolygon(Polygon polygon) { foreach (Pair3f pA in Pair3f.GetList(polygon.pointsList)) { foreach (Pair3f pB in Pair3f.GetList(polygon.pointsList)) { if (pA.B != pB.B && Vector2f.Distance(pA.B, pB.B) < precision) { pA.B.Push(Vector2f.Atan2(new Vector2f(pA.A), new Vector2f(pA.B)), precision); pA.B.Push(Vector2f.Atan2(new Vector2f(pA.B), new Vector2f(pA.C)), -precision); pB.B.Push(Vector2f.Atan2(new Vector2f(pB.A), new Vector2f(pB.B)), precision); pB.B.Push(Vector2f.Atan2(new Vector2f(pB.B), new Vector2f(pB.C)), -precision); } } } }
private void CreateCircleTexture(int diameter) { float radius = diameter / 2f; var blankTexture = new Texture2D(diameter, diameter, TextureFormat.RGBA32, false, true); for (int y = 0; y < diameter; y++) { for (int x = 0; x < diameter; x++) { bool isInside = Vector2f.Distance(new Vector2f(x, y), Vector2f.One * radius) < radius; blankTexture.SetPixel(x, y, isInside ? ColorF.White : ColorF.Transparent); } } blankTexture.Apply(); this.SaveTextureAsset("BlankTexture", blankTexture); Object.DestroyImmediate(blankTexture); }
private void picMap_MouseUp(object sender, MouseEventArgs e) { if (world == null) { return; } Scene[] scenes = world.Scenes; if (scenes == null) { return; } Vector2f clickPos = new Vector2f(e.X, e.Y); Scene scene = GetContainingScene(scenes, clickPos); if (scene == null) { return; } Actor closestActor = world.GetClosestActor(clickPos); Vector3f closestActorPos = closestActor.Position; float dist = Vector2f.Distance(new Vector2f(closestActorPos.X, closestActorPos.Y), clickPos); if (dist < 6f) { switch (closestActor.Category) { case ActorCategory.Gizmo: world.Me.UsePower(PowerName.Axe_Operate_Gizmo, closestActor); return; case ActorCategory.Item: if (closestActor.Type == ActorName.GoldCoin) { world.Me.UsePower(PowerName.Walk, closestActor.Position); } else { world.Me.UsePower(PowerName.PickupNearby, closestActor); } return; case ActorCategory.Monster: if (closestActor is NPC) { world.Me.UsePower(PowerName.Axe_Operate_NPC, closestActor); } else { world.Me.UsePower(PowerName.Punch, closestActor); } return; } } Vector2f relClickPos = new Vector2f( clickPos.X - scene.BoundingBox.Min.X, clickPos.Y - scene.BoundingBox.Min.Y); for (int i = 0; i < scene.NavCells.Length; i++) { NavCell cell = scene.NavCells[i]; if (!cell.BoundingBox.IsWithin(relClickPos)) { continue; } if (cell.Flags.HasFlag(NavCellFlags.AllowWalk)) { Vector3f dest = new Vector3f(clickPos.X, clickPos.Y, cell.BoundingBox.Center.Z); //bool direct = AI.IsDirectPath(world, world.Me.Position, dest); world.Me.UsePower(PowerName.Walk, dest); } return; } }
/// <summary>Get the closest distance between this <see cref="Box2f"/> and the <see cref="Vector2f"/>.</summary> public Single Distance( ref Vector2f point) { Vector2f nearest; NearestPointTo(ref point, out nearest); return point.Distance(ref nearest); }
private static void OnMouseButtonReleased(object sender, MouseButtonEventArgs e) { drawAimLine = false; // Spawn firework with appropriate velocity var mouseDownPositionF = new Vector2f(mouseDownPosition.X, mouseDownPosition.Y); var mousePosition = Mouse.GetPosition(wnd); var mousePositionF = new Vector2f(mousePosition.X, mousePosition.Y); var distance = mouseDownPositionF.Distance(mousePositionF); }
static private Slice2D SliceWithOneHole(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice) { Slice2D result = Slice2D.Create(); Polygon holeA = polygon.PointInHole(slice.First()); Polygon holeB = polygon.PointInHole(slice.Last()); Polygon holePoly = (holeA != null) ? holeA : holeB; if (polygon.PointInPoly(slice.First()) == false || polygon.PointInPoly(slice.Last()) == false) { if (holeA == holeB) { if (Slicer2D.complexSliceType == Slicer2D.SliceType.Regular) { return(result); } if (holeA == null) { Debug.LogError("Slicer2D: This happened when collider had a lot of paths but they were not holes"); return(result); } List <Vector2f> slice2 = new List <Vector2f> (slice); Polygon polyA = new Polygon(polygon.pointsList); Polygon polyB = new Polygon(slice); Polygon polyC = new Polygon(slice2); // Get First Point - NOT FINISHED WITH INTERSECTION int Add; List <Vector2f> list; List <Pair2f> iterateList = Pair2f.GetList(holeA.pointsList); Add = 0; list = new List <Vector2f> (); foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 1) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2f.Distance(list.First(), slice.First()) < Vector2f.Distance(list.First(), slice.Last())) { slice.Reverse(); } polyB.AddPoints(list); } Add = 0; list = new List <Vector2f> (); foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } foreach (Pair2f pair in iterateList) { List <Vector2f> intersect = MathHelper.GetListLineIntersectSlice(pair, slice2); if (intersect.Count > 0) { Add += intersect.Count; } if (Add == 2) { list.Add(pair.B); } } if (list.Count > 0) { if (Vector2f.Distance(list.First(), slice2.First()) < Vector2f.Distance(list.First(), slice2.Last())) { slice2.Reverse(); } polyC.AddPoints(list); } if (polyB.GetArea() > polyC.GetArea()) { Polygon swap = polyB; polyB = polyC; polyC = swap; } // Add holes to new created polygon foreach (Polygon poly in polygon.holesList) { if (poly != holeA && polyB.PolyInPoly(poly) == true) { polyB.AddHole(poly); } } if (Slicer2D.complexSliceType == Slicer2D.SliceType.FillSlicedHole) { result.AddPolygon(polyB); } polyA.AddHole(polyC); // Adds polygons if they are not in the hole foreach (Polygon poly in polygon.holesList) // Check for errors? { if (poly != holeA && polyC.PolyInPoly(poly) == false) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } else if (holePoly != null) { Polygon polyA = new Polygon(); Polygon polyB = new Polygon(holePoly.pointsList); polyB.pointsList.Reverse(); List <Vector2f> pointsA = VectorList2f.GetListStartingIntersectSlice(polygon.pointsList, slice); List <Vector2f> pointsB = VectorList2f.GetListStartingIntersectSlice(polyB.pointsList, slice); if (pointsA.Count < 1) { Debug.LogError("Slicer2D: " + pointsA.Count + " " + polygon.pointsList.Count); } polyA.AddPoints(pointsA); if (collisionSlice.Count > 0) { // pointsA empty if (Vector2f.Distance(pointsA.Last(), collisionSlice.Last()) < Vector2f.Distance(pointsA.Last(), collisionSlice.First())) { collisionSlice.Reverse(); } polyA.AddPoints(collisionSlice); } polyA.AddPoints(pointsB); if (collisionSlice.Count > 0) { collisionSlice.Reverse(); polyA.AddPoints(collisionSlice); } foreach (Polygon poly in polygon.holesList) // Check for errors? { if (poly != holePoly) { polyA.AddHole(poly); } } result.AddPolygon(polyA); return(result); } } return(result); }
public bool inRange(Vector2f point) { float dist = center.Distance(point); return(dist < maxDistance); }
public static bool InRange(this Vector2f A, Vector2f B, float Range) { return(A.Distance(B) < Range); }
public static float Distance(Vector2f a, Vector2f b) { return(Vector2f.Distance(a, b)); }
static private Slice2D SliceWithoutHoles(Polygon polygon, List <Vector2f> slice, List <Vector2f> collisionSlice) { Slice2D result = Slice2D.Create(); // Simple non-hole slice Polygon polyA = new Polygon(); Polygon polyB = new Polygon(); Polygon currentPoly = polyA; foreach (Pair2f p in Pair2f.GetList(polygon.pointsList)) { List <Vector2f> intersections = MathHelper.GetListLineIntersectSlice(p, slice); Vector2f intersection = null; if (intersections.Count() > 0) { intersection = intersections.First(); } if (intersections.Count > 0) // Only if 1 or 2 { if (intersections.Count == 2) { Vector2f first = intersections.First(); Vector2f last = intersections.Last(); if (Vector2f.Distance(last, p.A) < Vector2f.Distance(first, p.A)) { first = intersections.Last(); last = intersections.First(); } currentPoly.AddPoint(first); if (collisionSlice.Count > 0) { if (Vector2f.Distance(first, collisionSlice.Last()) < Vector2f.Distance(first, collisionSlice.First())) { collisionSlice.Reverse(); } currentPoly.AddPoints(collisionSlice); } currentPoly.AddPoint(last); currentPoly.AddPoint(p.B); currentPoly = polyB; if (collisionSlice.Count > 0) { currentPoly.AddPoints(collisionSlice); } currentPoly.AddPoint(last); currentPoly.AddPoint(first); currentPoly = polyA; } if (intersections.Count == 1) { currentPoly.AddPoint(intersection); if (collisionSlice.Count > 0) { if (Vector2f.Distance(intersection, collisionSlice.Last()) < Vector2f.Distance(intersection, collisionSlice.First())) { collisionSlice.Reverse(); } currentPoly.AddPoints(collisionSlice); } currentPoly = (currentPoly == polyA) ? polyB : polyA; currentPoly.AddPoint(intersection); } } currentPoly.AddPoint(p.B); } result.AddPolygon(polyA); result.AddPolygon(polyB); foreach (Polygon poly in result.polygons) { foreach (Polygon hole in polygon.holesList) { if (poly.PolyInPoly(hole) == true) { poly.AddHole(hole); } } } return(result); }
public void RayIntersectsSegment() { float eps = 1e-6f; Vector2f point; Ray2f ray; Segment2f seg; ray.Position = new Vector2f(0, 0); ray.Direction = new Vector2f(1, 0); seg.A = new Vector2f(0, 0); seg.B = new Vector2f(0, 1); bool intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsFalse(intersect); //at tangent ray.Position = new Vector2f(0, 0); ray.Direction = new Vector2f(1, 0); seg.A = new Vector2f(0, 0); seg.B = new Vector2f(-1, 0); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsFalse(intersect); //opposite ray.Position = new Vector2f(0, 0); ray.Direction = new Vector2f(1, 0); seg.A = new Vector2f(0, 0); seg.B = new Vector2f(1, 0); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsFalse(intersect); //parallel ray.Position = new Vector2f(0, 0); ray.Direction = new Vector2f(0, 0); seg.A = new Vector2f(0, 0); seg.B = new Vector2f(0, 0); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsFalse(intersect); //degenerate ray.Position = new Vector2f(0, 1); ray.Direction = new Vector2f(1, 0); seg.A = new Vector2f(1, 0); seg.B = new Vector2f(1, 2); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsTrue(intersect); // at 90 degree Assert.IsTrue(Vector2f.Distance(point, new Vector2f(1, 1)) < eps); ray.Position = new Vector2f(0, 1); ray.Direction = new Vector2f(1, -1); seg.A = new Vector2f(1, 0); seg.B = new Vector2f(-1, 1); ray.Direction.Normalize(); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsFalse(intersect); //parallel at 45 degree ray.Position = new Vector2f(0, 2); ray.Direction = new Vector2f(1, -1); seg.A = new Vector2f(1, 0); seg.B = new Vector2f(1, 2); ray.Direction.Normalize(); intersect = RayIntersections2f.RayIntersectsSegment(ray, seg, out point); Assert.IsTrue(intersect); // at 45 degree Assert.IsTrue(Vector2f.Distance(point, new Vector2f(1, 1)) < eps); }
/// <summary> /// Obtains a list of vertexes that represent the polyline approximating the curve segments as necessary. /// </summary> /// <param name="bulgePrecision">Curve segments precision (a value of zero means that no approximation will be made).</param> /// <param name="weldThreshold">Tolerance to consider if two new generated vertexes are equal.</param> /// <param name="bulgeThreshold">Minimun distance from which approximate curved segments of the polyline.</param> /// <returns>The return vertexes are expresed in object coordinate system.</returns> public List <Vector2f> PoligonalVertexes(int bulgePrecision, double weldThreshold, double bulgeThreshold) { List <Vector2f> ocsVertexes = new List <Vector2f>(); int index = 0; foreach (LightWeightPolylineVertex vertex in this.Vertexes) { double bulge = vertex.Bulge; Vector2f p1; Vector2f p2; if (index == this.Vertexes.Count - 1) { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[0].Location.X, this.vertexes[0].Location.Y); } else { p1 = new Vector2f(vertex.Location.X, vertex.Location.Y); p2 = new Vector2f(this.vertexes[index + 1].Location.X, this.vertexes[index + 1].Location.Y); } if (!p1.Equals(p2, weldThreshold)) { if (bulge == 0 || bulgePrecision == 0) { ocsVertexes.Add(p1); } else { double c = Vector2f.Distance(p1, p2); if (c >= bulgeThreshold) { double s = (c / 2) * Math.Abs(bulge); double r = ((c / 2) * (c / 2) + s * s) / (2 * s); double theta = (double)(4 * Math.Atan(Math.Abs(bulge))); double gamma = (double)((Math.PI - theta) / 2); double phi; if (bulge > 0) { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) + gamma; } else { phi = Vector2f.AngleBetween(Vector2f.UnitX, p2 - p1) - gamma; } Vector2f center = new Vector2f((double)(p1.X + r * Math.Cos(phi)), (double)(p1.Y + r * Math.Sin(phi))); Vector2f a1 = p1 - center; double angle = 4 * ((double)(Math.Atan(bulge))) / (bulgePrecision + 1); ocsVertexes.Add(p1); for (int i = 1; i <= bulgePrecision; i++) { Vector2f curvePoint = new Vector2f(); Vector2f prevCurvePoint = new Vector2f(this.vertexes[this.vertexes.Count - 1].Location.X, this.vertexes[this.vertexes.Count - 1].Location.Y); curvePoint.X = center.X + (double)(Math.Cos(i * angle) * a1.X - Math.Sin(i * angle) * a1.Y); curvePoint.Y = center.Y + (double)(Math.Sin(i * angle) * a1.X + Math.Cos(i * angle) * a1.Y); if (!curvePoint.Equals(prevCurvePoint, weldThreshold) && !curvePoint.Equals(p2, weldThreshold)) { ocsVertexes.Add(curvePoint); } } } else { ocsVertexes.Add(p1); } } } index++; } return(ocsVertexes); }