public static Point2D GetClosestPointOnSegment(Segment2D segment, Point2D point, out double distance) { double bot; int i; double t; //the relative position of the point Pn to the SEGMENT // // If the line segment is actually a point, then the answer is easy. // if (segment.Length == 0) { t = 0.0; } else { bot = Math.Pow(segment.x2 - segment.x1, 2) + Math.Pow(segment.y2 - segment.y1, 2); t = (point.x - segment.x1) * (segment.x2 - segment.x1) + (point.y - segment.y1) * (segment.y2 - segment.y1); t = t / bot; t = Math.Min( Math.Max(t, 0.0), 1.0 ); } Point2D closestPoint; closestPoint.x = segment.x1 + t * (segment.x2 - segment.x1); closestPoint.y = segment.y1 + t * (segment.y2 - segment.y1); distance = point.GetDistance(closestPoint); return closestPoint; }
/// <summary> /// 図形パスの開始Nodeを用いてFigurePathクラスを初期化する. /// </summary> /// <param name="start_point"></param> public FigurePath(Point2D start_point) { points = new List<Point2D>(); lines = new List<LineSegment2D>(); min_x = max_x = start_point.X; min_y = max_y = start_point.Y; envelope = new Rectangle(start_point, 0, 0, 0); points.Add(start_point); }
public MazeNode(Point2D position, MazeSpace Room, MazeWall Door) : base() { this.position = position; this.Room = Room; this.Door = Door; if (this.Door != null) this.MazeGraphNodeType = MazeNodeType.GateNode; else this.MazeGraphNodeType = MazeNodeType.SpaceNode; incommingGraphArcs = new ArrayList(); outgoingGraphArcs = new ArrayList(); }
public bool ContainsPoint(Point2D p) { int i; bool value; double x1; double x2; double y1; double y2; value = false; for (i = 0; i < RoomPolygon.points.Length; i++) { x1 = RoomPolygon.points[i].x; y1 = RoomPolygon.points[i].y; if (i < RoomPolygon.points.Length - 1) { x2 = RoomPolygon.points[i + 1].x; y2 = RoomPolygon.points[i + 1].y; } else { x2 = RoomPolygon.points[0].x; y2 = RoomPolygon.points[0].y; } if ((y1 < p.y && p.y <= y2) || (p.y <= y1 && y2 < p.y)) { if ((p.x - x1) - (p.y - y1) * (x2 - x1) / (y2 - y1) < 0) { value = !value; } } } return value; }
private void ProcessSnaps(ref PointF snappedPoint, PointF referencePoint) { if (snapToAngle) { if (Math.Abs(snappedPoint.X - referencePoint.X) < Math.Abs(snappedPoint.Y - referencePoint.Y)) { snappedPoint.X = referencePoint.X; } else { snappedPoint.Y = referencePoint.Y; } } if (snapToGrid) { snappedPoint.X = (float)Math.Round(snappedPoint.X / 10) * 10; snappedPoint.Y = (float)Math.Round(snappedPoint.Y / 10) * 10; } if (snapToWall) { tempPoints[0] = snappedPoint; invertedMazeMatrix.TransformPoints(tempPoints); if (mazeWalls == null || mazeWalls.Count == 0) return; double distance, minDistance = double.MaxValue; Point2D mindistancePoint = new Point2D(0, 0); foreach (MazeWall wall in mazeWalls) { if (wall != selectedWall) { Point2D p = GeometryHelper.GetClosestPointOnSegment(wall.Segment, tempPoints[0], out distance); if (distance < minDistance) { minDistance = distance; mindistancePoint = p; } } } tempPoints[0] = mindistancePoint; mazeBitmapGraphics.Transform.TransformPoints(tempPoints); snappedPoint = tempPoints[0]; } }
public RegularRectangle(RegularRectangle source) { starting_point = new Point2D(source.starting_point.X, source.starting_point.Y); diagonal = new Vector3D(source.diagonal.X, source.diagonal.Y, 0); }
/// <summary> /// 検査点が<c>FigurePath</c>で表された図形パスの内部に存在するかどうか.閉じられた図形パスが存在しない場合にはnullを返す. /// </summary> /// <param name="p">検査点</param> /// <returns></returns> public bool? IsInside(Point2D p) { if (Count >= 3) { if ((p.X < min_x) | (p.X > max_x) | (p.Y < min_y) | (p.Y > max_y)) //パス包含長方形の外部 { return false; } else { bool temp2 = false; foreach (LineSegment2D line in lines) { temp2 |= line.IsPointOnLineSegment(p); } if (temp2) //パス境界上 { return false; } else { double size = Math.Sqrt((max_x - min_x) * (max_x - min_x) + (max_y - min_y) * (max_y - min_y)); Random rnd = new Random(); LineSegment2D ray; bool ray_is_crossing_on_point; do { double theta = rnd.NextDouble() * 2.0 * Math.PI; ray = new LineSegment2D(p, new Point2D(p.X + size * Math.Cos(theta), p.Y + size * Math.Sin(theta))); ray_is_crossing_on_point = false; foreach (Point2D tested_point in points) { ray_is_crossing_on_point |= ray.IsPointOnLineSegment(tested_point); } } while (ray_is_crossing_on_point); //パスのノード上を通過することのないレイを選択 int crossing_count = 0; foreach (LineSegment2D select_ls in lines) { if (select_ls.Intersects(ray)) { crossing_count++; } } return crossing_count % 2 == 0 ? false : true; } } } else { return null; } }
public void LoadAll(String filename) { JToken tempJObject; StreamReader reader = File.OpenText(filename); JObject o = (JObject)JToken.ReadFrom(new JsonTextReader(reader)); if (o.TryGetValue("name", out tempJObject)) worldName = o.GetValue("name").ToString(); if (o.TryGetValue("timeout", out tempJObject)) iWorldTimeout = (int)o.GetValue("timeout"); mazeWalls = new ArrayList(); Hashtable mazeWallsById = new Hashtable(); mazeRobots = new ArrayList(); mazeVictims = new ArrayList(); mazeSpaces = new ArrayList(); Hashtable mazeSpacesById = new Hashtable(); mazeGraph = new MazeGraph(); mazeNodeNodes = new ArrayList(); mazeSpaceNode = new ArrayList(); mazeSpaceRobots = new ArrayList(); foreach (JObject jObject in o.GetValue("walls").Children()) { MazeWall mazeWall = new MazeWall( new Point2D((double)((JObject)jObject.GetValue("from")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("from")).GetValue("y") * 100), new Point2D((double)((JObject)jObject.GetValue("to")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("to")).GetValue("y") * 100), (float)jObject.GetValue("width") * 100, (float)jObject.GetValue("height") * 100, Color.FromArgb(Convert.ToInt32((string)jObject.GetValue("color"), 16))); if (mazeWall.Color.A == 0) mazeWall.Color = Color.LightGray; mazeWall.ID = (string)jObject.GetValue("id"); mazeWalls.Add(mazeWall); mazeWallsById.Add((string)jObject.GetValue("id"), mazeWall); } if (o.GetValue("gates") != null) { foreach (JObject jObject in o.GetValue("gates").Children()) { MazeWall mazeWall = new MazeWall( new Point2D((double)((JObject)jObject.GetValue("from")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("from")).GetValue("y") * 100), new Point2D((double)((JObject)jObject.GetValue("to")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("to")).GetValue("y") * 100), 0, 0, Color.Black); mazeWall.MazeWallType = MazeWallType.gate; string kind = (string)jObject.GetValue("kind"); mazeWall.MazeDoorType = (kind == "door" ? MazeGateType.door : (kind == "passage" ? MazeGateType.passage : MazeGateType.doorOneWayFromTo)); //doorOneWayFromTo will be changed later mazeWall.blocked = (double)jObject.GetValue("blocked"); mazeWall.ID = (string)jObject.GetValue("id"); mazeWalls.Add(mazeWall); mazeWallsById.Add((string)jObject.GetValue("id"), mazeWall); } } if (o.GetValue("robots") != null) { JToken tmp; Point2D? target; foreach (JObject jObject in o.GetValue("robots").Children()) { if (jObject.TryGetValue("target", out tmp)) target = new Point2D((double)((JObject)jObject.GetValue("target")).GetValue("x"), (double)((JObject)jObject.GetValue("target")).GetValue("y")); else target = null; MazeRobot mazeRobot = new MazeRobot( (string)jObject.GetValue("type"), (string)jObject.GetValue("id"), new Point2D((double)((JObject)jObject.GetValue("location")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("location")).GetValue("y") * 100), (float)((JObject)jObject.GetValue("location")).GetValue("z") * 100, //new Point2D((double)((JObject)jObject.GetValue("target")).GetValue("x"),(double)((JObject)jObject.GetValue("target")).GetValue("y")) target ); mazeRobot.ID = (string)jObject.GetValue("id"); mazeRobots.Add(mazeRobot); } } if (o.GetValue("victims") != null) { foreach (JObject jObject in o.GetValue("victims").Children()) { MazeVictim mazeVictim = new MazeVictim( new Point2D((double)((JObject)jObject.GetValue("position")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("position")).GetValue("y") * 100)); mazeVictim.ID = (string)jObject.GetValue("id"); mazeVictims.Add(mazeVictim); } } Hashtable wallsBySpaceId = new Hashtable(); if (o.GetValue("space-walls") != null) { foreach (JObject jObject in o.GetValue("space-walls").Children()) { string spaceId = (string)jObject.GetValue("spaceId"); string wallId = (string)jObject.GetValue("wallId"); if (wallsBySpaceId.ContainsKey(spaceId)) { ((ArrayList)wallsBySpaceId[spaceId]).Add(mazeWallsById[wallId]); } else { ArrayList newArrayList = new ArrayList(); newArrayList.Add(mazeWallsById[wallId]); wallsBySpaceId[spaceId] = newArrayList; } } } if (o.GetValue("space-gates") != null) { foreach (JObject jObject in o.GetValue("space-gates").Children()) { string spaceId = (string)jObject.GetValue("spaceId"); string wallId = (string)jObject.GetValue("gateId"); if (wallsBySpaceId.ContainsKey(spaceId)) { ((ArrayList)wallsBySpaceId[spaceId]).Add(mazeWallsById[wallId]); } else { ArrayList newArrayList = new ArrayList(); newArrayList.Add(mazeWallsById[wallId]); wallsBySpaceId[spaceId] = newArrayList; } } } if (o.GetValue("spaces") != null) { foreach (JObject jObject in o.GetValue("spaces").Children()) { MazeSpace newRoom = new MazeSpace((ArrayList)wallsBySpaceId[(string)jObject.GetValue("id")]); newRoom.ID = (string)jObject.GetValue("id"); newRoom.MazeRoomType = (MazeSpaceType)System.Enum.Parse(typeof(MazeSpaceType), (string)jObject.GetValue("kind")); newRoom.Function = (string)jObject.GetValue("function"); newRoom.Name = (string)jObject.GetValue("name"); newRoom.ExpectedPersonCount = (int)jObject.GetValue("expectedPersonCount"); if (jObject.TryGetValue("searched", out tempJObject)) newRoom.Searched = (int)jObject.GetValue("searched"); mazeSpaces.Add(newRoom); mazeSpacesById[newRoom.ID] = newRoom; foreach (MazeWall roomWall in newRoom.Walls) { if (roomWall.RoomFrom == null) roomWall.RoomFrom = newRoom; else roomWall.RoomTo = newRoom; } } } /////////////////////////// graph Hashtable spacesByNodeId = new Hashtable(); if (o.GetValue("space-nodes") != null) { foreach (JObject jObject in o.GetValue("space-nodes").Children()) { spacesByNodeId[(string)jObject.GetValue("nodeId")] = mazeSpacesById[(string)jObject.GetValue("spaceId")]; } } Hashtable gatesByNodeId = new Hashtable(); if (o.GetValue("gate-nodes") != null) { foreach (JObject jObject in o.GetValue("gate-nodes").Children()) { gatesByNodeId[(string)jObject.GetValue("nodeId")] = mazeWallsById[(string)jObject.GetValue("gateId")]; } } Hashtable nodesById = new Hashtable(); if (o.GetValue("nodes") != null) { foreach (JObject jObject in o.GetValue("nodes").Children()) { MazeNode node = new MazeNode(new Point2D((double)((JObject)jObject.GetValue("position")).GetValue("x") * 100, (double)((JObject)jObject.GetValue("position")).GetValue("y") * 100), (MazeSpace)spacesByNodeId[(string)jObject.GetValue("id")], gatesByNodeId[(string)jObject.GetValue("id")] as MazeWall); node.ID = (string)jObject.GetValue("id"); nodesById[node.ID] = node; mazeGraph.AddNode(node); } } if (o.GetValue("node-nodes") != null) { foreach (JObject jObject in o.GetValue("node-nodes").Children()) { MazeNode fromNode = (MazeNode)nodesById[(string)jObject.GetValue("nodeFromId")]; MazeNode toNode = (MazeNode)nodesById[(string)jObject.GetValue("nodeToId")]; if (fromNode.Door != null && (fromNode.Door.MazeDoorType == MazeGateType.doorOneWayFromTo || fromNode.Door.MazeDoorType == MazeGateType.doorOneWayToFrom)) { if (fromNode.Room == fromNode.Door.RoomFrom) fromNode.Door.MazeDoorType = MazeGateType.doorOneWayFromTo; else fromNode.Door.MazeDoorType = MazeGateType.doorOneWayToFrom; } mazeGraph.AddArc(fromNode, toNode); mazeNodeNodes.Add(new MazeNodeNodes(jObject.GetValue("nodeFromId").ToString(), jObject.GetValue("nodeToId").ToString(), double.Parse(jObject.GetValue("cost").ToString()), double.Parse(jObject.GetValue("blocked").ToString()))); } } if (o.GetValue("space-nodes") != null) { foreach (JObject jObject in o.GetValue("space-nodes").Children()) { mazeSpaceNode.Add(new MazeSpaceNodes(jObject.GetValue("type").ToString(), jObject.GetValue("spaceId").ToString(), jObject.GetValue("nodeId").ToString())); } } if (o.GetValue("space-robots") != null) { foreach (JObject jObject in o.GetValue("space-robots").Children()) { mazeSpaceRobots.Add(new MazeSpaceRobots(jObject.GetValue("type").ToString(), jObject.GetValue("spaceId").ToString(), jObject.GetValue("robotId").ToString())); } } reader.Close(); }
public Rectangle(Point2D center, double h, double w, double angle) { this.center = center; height = h; width = w; this.angle = angle; }
public Point2D(Point2D source) : base(source.X,source.Y) { }
/// <summary> /// <c>Point2D p</c>がLineSegmentから見て右半面に存在するかどうか. /// </summary> /// <param name="p"></param> /// <returns></returns> public bool IsPointRightSide(Point2D p) { var vect1 = (Vector2D)p1 - (Vector2D)p; var vect2 = (Vector2D)p2 - (Vector2D)p; return Vector2D.CrossProduct(vect1, vect2).Z < 0 ? true : false; }
/// <summary> /// Node p がLineSegmentで表される線分上に存在するかどうか.(端点含む) /// </summary> /// <param name="p"></param> /// <returns></returns> public bool IsPointOnLineSegment(Point2D p) { if (IsPointOnLine(p)) //直線上 { var vect1 = (Vector2D)p1 - (Vector2D)p; var vect2 = (Vector2D)p2 - (Vector2D)p; return vect1 * vect2 <= 0 ? true : false; //0で端点上,負で線分内部 } else { return false; } }
public double DistanceTo(Point2D p) { var temp1 = (Vector2D)p - (Vector2D)p1; var temp2 = (Vector2D)p2 - (Vector2D)p1; return temp1.Length * Math.Sin(Vector2D.Angle(temp1, temp2)); }
/// <summary> /// 線分の始点と終点を用いてLineSegmentクラスを初期化する. /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> public LineSegment2D(Point2D p1, Point2D p2) { this.p1 = p1; this.p2 = p2; Length = Math.Sqrt((p1.X - p2.X) * (p1.X - p2.X) + (p1.Y - p2.Y) * (p1.Y - p2.Y)); }
/// <summary> /// /// </summary> private void BuildPolygon() { Point2D[] points = new Point2D[Walls.Count]; points[0] = (Walls[0] as MazeWall).points[0]; ArrayList wallsCopy = (ArrayList) Walls.Clone(); wallsCopy.RemoveAt(0); for (int i = 1; i < points.Length; i++) { //find adjacent wall... the closest foreach (MazeWall wall in wallsCopy) { if (Point2D.GetDistance(wall.points[0], points[i - 1]) < 0.01) { points[i] = wall.points[1]; wallsCopy.Remove(wall); break; } else if (Point2D.GetDistance(wall.points[1], points[i - 1]) < 0.01) { points[i] = wall.points[0]; wallsCopy.Remove(wall); break; } } } roomPolygon = new Polygon2D(points); }
private void timer1_Tick(object sender, EventArgs e) { double x = rnd.NextDouble(); double y = rnd.NextDouble(); Point2D newpoint = new Point2D(x, y); if (samplebubble.GetPath().IsInside(newpoint) == true) { samplebubble.AddBubble(new Bubble(false, x,y) { Diam = 0.05 }); } if (samplebubble.Count >= 200) { timer1.Stop(); } Invalidate(); }
public RegularRectangle(Point2D p1, Point2D p2) { starting_point = new Point2D(p1.X < p2.X ? p1.X : p2.X, p1.Y < p2.Y ? p1.Y : p2.Y); diagonal = new Vector3D(Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y), 0); }
public RegularRectangle(double top, double bottom, double right, double left) { starting_point = new Point2D(left, bottom); diagonal = new Vector3D(right - left, top - bottom, 0); }
/// <summary> /// 図形パスを構成する<c>Point2D</c>を追加する. /// </summary> /// <param name="p"></param> public void AddPoint(Point2D p) { points.Add(p); if (p.X < min_x) { min_x = p.X; } else if (p.X > max_x) { max_x = p.X; } if (p.Y < min_y) { min_y = p.Y; } else if (p.Y > max_y) { max_y = p.Y; } if (points.Count == 2) { lines.Add(new LineSegment2D(points[0], points[1])); } else if (points.Count == 3) { lines.Add(new LineSegment2D(points[1], points[2])); lines.Add(new LineSegment2D(points[2], points[0])); } else { lines.RemoveAt(lines.Count - 1); lines.Add(new LineSegment2D(points[points.Count - 2], points[points.Count - 1])); lines.Add(new LineSegment2D(points[points.Count - 1], points[0])); } }