/// <summary> /// 交点を有するかどうか /// </summary> /// <param name="ls"></param> /// <returns></returns> public bool Intersects(LineSegment2D ls) { double temp = (p2.X - p1.X) * (ls.p2.Y - ls.p1.Y) - (p2.Y - p1.Y) * (ls.p2.X - ls.p1.X); double temp_r = (ls.p2.Y - ls.p1.Y) * (ls.p1.X - p1.X) - (ls.p2.X - ls.p1.X) * (ls.p1.Y - p1.Y); double temp_s = (p2.Y - p1.Y) * (ls.p1.X - p1.X) - (p2.X - p1.X) * (ls.p1.Y - p1.Y); if (temp == 0) //並行 { if (temp_r != 0) { return false; } else //同一直線上 { if (ls.IsPointOnLineSegment(p1) | ls.IsPointOnLineSegment(p2)) { return true; } else { return false; } } } else { double r = temp_r / temp; double s = temp_s / temp; if ((r < 0) | (1 < r) | (s < 0) | (1 < s)) { return false; } else { return true; } } }
/// <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; } }