/// <summary> /// Determines whether the last click is a double click. /// </summary> /// <param name="sender">The sender.</param> /// <param name="position">The position.</param> /// <returns>True if the click was a double click.</returns> internal static bool IsDoubleClick(object sender, Point position) { long clickTicks = DateTime.Now.Ticks; long elapsedTicks = clickTicks - lastClickTicks; long elapsedTime = elapsedTicks / TimeSpan.TicksPerMillisecond; bool quickClick = elapsedTime <= DoubleClickSpeed; bool senderMatch = lastSender != null && sender.Equals(lastSender.Target); if (senderMatch && quickClick && position.Distance(lastPosition) <= MaxMoveDistance) { // Double click! lastClickTicks = 0; lastSender = null; return true; } // Not a double click lastClickTicks = clickTicks; lastPosition = position; if (!quickClick) { lastSender = new WeakReference(sender); } return false; }
/// <summary> /// Computes the closest point on this line segment to another point. /// </summary> /// <returns> /// A Coordinate which is the closest point on the line segment to the point p. /// </returns> public static Point ClosestPoint(Point p, Point lineSegFrom, Point lineSegTo) { var factor = ProjectionFactor(p, lineSegFrom, lineSegTo); if ((factor > 0) && (factor < 1)) return Project(p, lineSegFrom, lineSegTo); var dist0 = lineSegFrom.Distance(p); var dist1 = lineSegTo.Distance(p); return dist0 < dist1 ? lineSegFrom : lineSegTo; }
/// <summary> /// Computes the closest point on this line segment to another point. /// </summary> /// <param name="p">The point to find the closest point to.</param> /// <returns> /// A Coordinate which is the closest point on the line segment to the point p. /// </returns> public static Point ClosestPoint(Point p, Point LineSegFrom, Point LineSegTo) { var factor = ProjectionFactor(p, LineSegFrom, LineSegTo); if (factor > 0 && factor < 1) return Project(p, LineSegFrom, LineSegTo); var dist0 = LineSegFrom.Distance(p); var dist1 = LineSegTo.Distance(p); return dist0 < dist1 ? LineSegFrom : LineSegTo; }
/// <summary> /// Checks if one of the players won /// </summary> /// <returns>playerId if someone won, -1 if no one did</returns> public string CheckVictory(int x, int y, int z) { /* * Basic winner finding algo: * 1. generate all posible direction vectors ([-1,-1,-1], [-1,-1,0] ... ) * 2. move from current position in vector direction while its posible, getting point A * 3. move from current position in reverse vector direction while posible, getting point B * 4. if distance between A and B is field size, we've got the winner! * */ var who = Field[x, y, z]; if (who == 0) return null; var ways = new[] { -1, 0, 1 }; foreach (var wx in ways) { foreach (var wy in ways) { foreach (var wz in ways) { if (wx == 0 && wy == 0 && wz == 0) continue; Point pa = new Point(x, y, z); Point pb = new Point(x, y, z); Point newA; while ((newA = pa.Move(wx, wy, wz, _fieldSize)) != null && Field[newA.X, newA.Y, newA.Z] == who) { pa = newA; } Point newB; while ((newB = pb.Move(-wx, -wy, -wz, _fieldSize)) != null && Field[newB.X, newB.Y, newB.Z] == who) { pb = newB; } if (pa.Distance(pb) == _fieldSize) { return Players[who - 1]; } } } } return null; }
public List<Node> GetShortestPath(Point startPoint, Point endPoint) { if (startPoint == null || endPoint == null) return null; // We create and place the start a goal node into the graph Node startNode = new Node(startPoint); Node endNode = new Node(endPoint); List<Node> path = null; if (false && startPoint.Distance(endPoint) > _cacheAcceptanceDistance) { // Check to see if this path is cached List<Node> cachedPath = GetCachedPath(startPoint, endPoint); if (cachedPath != null) { // We have a close match, build the shortest path using the cached path path = DStarLite(startNode, endNode, cachedPath); } else { // No close match, use A* path = AStar(startNode, endNode); } } else { // The points are close, just use A* path = AStar(startNode, endNode); } AddPathToShortestPathCache(path); // Return the path if there is one return (path != null && path.Contains(startNode)) ? SmoothPath(path) : path; }
/// <summary> /// Computes the distance from a point p to a line segment AB. /// Note: NON-ROBUST! /// </summary> /// <param name="p">The point to compute the distance for.</param> /// <param name="a">One point of the line.</param> /// <param name="b">Another point of the line (must be different to A).</param> /// <returns> The distance from p to line segment AB.</returns> public static double DistancePointLine(Point p, Point a, Point b) { // if start == end, then use pt distance if (a.Equals(b)) return p.Distance(a); // otherwise use comp.graphics.algorithms Frequently Asked Questions method /*(1) AC dot AB r = --------- ||AB||^2 r has the following meaning: r=0 Point = A r=1 Point = B r<0 Point is on the backward extension of AB r>1 Point is on the forward extension of AB 0<r<1 Point is interior to AB */ var r = ((p.X - a.X)*(b.X - a.X) + (p.Y - a.Y)*(b.Y - a.Y)) / ((b.X - a.X)*(b.X - a.X) + (b.Y - a.Y)*(b.Y - a.Y)); if (r <= 0.0) return p.Distance(a); if (r >= 1.0) return p.Distance(b); /*(2) (Ay-Cy)(Bx-Ax)-(Ax-Cx)(By-Ay) s = ----------------------------- Curve^2 Then the distance from C to Point = |s|*Curve. */ var s = ((a.Y - p.Y)*(b.X - a.X) - (a.X - p.X)*(b.Y - a.Y)) / ((b.X - a.X)*(b.X - a.X) + (b.Y - a.Y)*(b.Y - a.Y)); return Math.Abs(s)*Math.Sqrt((b.X - a.X)*(b.X - a.X) + (b.Y - a.Y)*(b.Y - a.Y)); }
public Line(Point beg, Point end) { double l = beg.Distance(end); if (FP.eq(l, Math.PI)) { Debug.Assert(FP.eq(beg.ra, end.ra)); phi = -Math.PI/2; theta = Math.PI/2; psi = beg.ra < 0.0 ? Math.PI*2 + beg.ra : beg.ra; length = Math.PI; return; } if (beg.Equals(end)) { phi = Math.PI/2; theta = beg.dec; psi = beg.ra - Math.PI/2; length = 0.0; } else { Point3D beg3d = new Point3D(beg); Point3D end3d = new Point3D(end); Point3D tp = new Point3D(); Point spt = beg3d.cross(end3d).toSpherePoint(); Euler euler = new Euler(); euler.phi = - spt.ra - Math.PI/2; euler.theta = spt.dec - Math.PI/2; euler.psi = 0.0 ; euler.psi_a = Euler.AXIS_Z; euler.theta_a = Euler.AXIS_X; euler.phi_a = Euler.AXIS_Z; euler.transform(tp, beg3d); spt = tp.toSpherePoint(); // invert phi = spt.ra; theta = -euler.theta; psi = -euler.phi; length = l; } }
public Selection GetSelection(Point point, double precision, bool inMotion = false) { if (point.Distance (Start) < precision) { return new Selection (this, SelectionPosition.LineStart); } else if (Points.Count == 2 && point.Distance (Stop) < precision) { return new Selection (this, SelectionPosition.LineStop); } return null; }