示例#1
0
bool IsSameEnough(const Tile& lhs, const Tile& rhs) {
  for (const auto& num : kAllEdgeNumber) {
    if (!IsSameEnough(lhs.GetEdge(num), rhs.GetEdge(num))) {
      return false;
    }
  }
  return true;
}
示例#2
0
bool TileCollection::IsOverlapCursor(const Tile& cursor) const {
  for (const auto& edge : outline_edges_) {
    for (const auto& num : kAllEdgeNumber) {
      const auto cursor_edge = cursor.GetEdge(num);
      if (IsIntersectLineSegment(cursor_edge.Begin(), cursor_edge.End(),
                                 edge.Begin(), edge.End())) {
        return true;
      }
    }
  }
  return false;
}
示例#3
0
MaybeEdges TileCollection::TryOutlineEdges(const Tile& tile,
                                           bool is_add) const {
  using std::begin;
  using std::end;
  using EdgeList = std::list<Edge>;
  using EdgeListIter = EdgeList::iterator;
  EdgeList edge_list(begin(outline_edges_), end(outline_edges_));
  const auto get_overlap_iter = [&edge_list](const Edge& edge) {
    return std::find_if(begin(edge_list), end(edge_list),
                        [&edge](const Edge& candidate) {
                          return IsSameEnough(candidate, edge);
                        });
  };
  std::vector<EdgeListIter> to_be_removed;
  EdgeNum start_add_num = kEdge3, end_add_num = kEdge3;
  int num_of_interchange = 0;
  bool is_previous_overlap =
      get_overlap_iter(tile.GetEdge(kEdge3)) != end(edge_list);
  for (const auto& num : kAllEdgeNumber) {
    const auto it = get_overlap_iter(tile.GetEdge(num));
    const bool is_current_overlap = it != end(edge_list);
    if (is_current_overlap) {
      to_be_removed.push_back(it);
    }
    if (is_previous_overlap != is_current_overlap) {
      ++num_of_interchange;
      if (is_current_overlap) {
        if (is_add) {
          start_add_num += num;
        } else {  // is_remove
          end_add_num = num;
        }
      } else {  // is_previous_overlap == true
        if (is_add) {
          end_add_num += num;
        } else {  // is_remove
          start_add_num = num;
        }
      }
    }
    is_previous_overlap = is_current_overlap;
  }
  if (to_be_removed.empty()) {
    if (is_add) {
      Q_UNREACHABLE();
    } else {  // is_remove
      return boost::none;
    }
  }
  Q_ASSERT(num_of_interchange % 2 == 0);
  if (num_of_interchange != 2) {
    return boost::none;
  }
  auto insert_point = begin(edge_list);
  for (const auto removed : to_be_removed) {
    insert_point = edge_list.erase(removed);
  }
  if (is_add) {
    for (EdgeNum num = start_add_num; num != end_add_num; --num) {
      insert_point = edge_list.insert(insert_point, tile.GetEdge(num));
    }
  } else {  // is_remove
    for (EdgeNum num = start_add_num; num != end_add_num; ++num) {
      if (const auto internal = GetCorrespondingEdge(tile.GetEdge(num))) {
        insert_point = edge_list.insert(insert_point, *internal);
      } else {
        Q_UNREACHABLE();
      }
    }
  }
  return Edges{begin(edge_list), end(edge_list)};
}