Skip to content

Commit

Permalink
Merge pull request #108 from AsPJT/feature-astar-view
Browse files Browse the repository at this point in the history
移動経路を矢印で可視化する機能を追加
  • Loading branch information
AsPJT authored Oct 19, 2024
2 parents 1461826 + af5612b commit 0475d42
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 19 deletions.
6 changes: 3 additions & 3 deletions Data/Simulations/Settings.tsv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
key value ja-JP
key value ja-JP
#Time -------------------- #時間 --------------------------------------------------
start_julian_day 1319309 シミュレーション開始日(ユリウス日)
steps_per_year 12 1年あたりのStepの数(step/年)
Expand Down Expand Up @@ -40,8 +40,8 @@ max_move_distance 1600 最大移動距離(cell)
move_probability 0.0021 移動確率
ocean_cost 1.1 海上の通行コスト
coast_cost 0.7 海岸の通行コスト
land_cost 1.5 傾斜度0度の陸上の通行コスト
land_cost 4.5 傾斜度0度の陸上の通行コスト
move_redo 10 移動再試行回数
move_method astar 移動の手法(astar/random)
move_astar_loop 40 A*を行うルート数
move_astar_loop 5 A*を行うルート数
move_astar_distance 64 A*を行うルート間隔
62 changes: 61 additions & 1 deletion Library/PAX_MAHOROBA/LocationPoint.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -739,13 +739,73 @@ namespace paxs {
pop_original = settlement.getSNP() * 75.0;
break;
}

const std::uint_least8_t pop = (pop_original >= 75) ? 75 : static_cast<std::uint_least8_t>(pop_original);
paxg::Circle(draw_pos,
1.0f + (settlement.getPopulation() / 40.0f)//2.0f
).draw(getColor(pop));
}

#ifdef PAXS_USING_SIV3D
if (settlement.getOldPosition().x != -1 && settlement.getOldPosition().x != 0) {
if (settlement.getPositions().size() >= 1) {

// 過去の位置
auto old_lli = lli;
old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(
settlement.getOldPosition().x,
settlement.getOldPosition().y), 10));
const paxg::Vec2i draw_old_pos = paxg::Vec2i{
static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};

s3d::Array<s3d::Vec2> va;
va << s3d::Vec2{ draw_pos.x(), draw_pos.y() };
for (auto&& p : settlement.getPositions()) {
auto one_lli = lli;
one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(p.x, p.y), 10));
const paxg::Vec2i draw_one_pos = paxg::Vec2i{
static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};
va << s3d::Vec2{ draw_one_pos.x(), draw_one_pos.y() };
}
va << s3d::Vec2{ draw_old_pos.x(), draw_old_pos.y() };

const s3d::Spline2D spline(va);
spline.draw(2, Palette::Black);

// 過去の位置
auto one_lli = lli;
one_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(
settlement.getPositions()[0].x,
settlement.getPositions()[0].y), 10));
const paxg::Vec2i draw_one_pos = paxg::Vec2i{
static_cast<int>((one_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<int>(double(paxg::Window::height()) - ((one_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};
s3d::Line{ draw_one_pos.x(), draw_one_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(0.1, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
}
else {
// 過去の位置
auto old_lli = lli;
old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(),
paxs::Vector2<int>(
settlement.getOldPosition().x,
settlement.getOldPosition().y), 10));
const paxg::Vec2i draw_old_pos = paxg::Vec2i{
static_cast<int>((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())),
static_cast<int>(double(paxg::Window::height()) - ((old_lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height())))
};
s3d::Line{ draw_old_pos.x(), draw_old_pos.y(), draw_pos.x(), draw_pos.y() }.drawArrow(2, s3d::Vec2{ 8, 16 }, s3d::Palette::Black);
}
}
#endif

}

}
Expand Down
52 changes: 37 additions & 15 deletions Library/PAX_SAPIENTICA/Simulation/Settlement.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ namespace paxs {
class AStar {
using AStarVec2 = paxs::Vector2<GridType>;
private:
//始点 元の座標
AStarVec2 start_vec2_original{};
//終点 元の座標
AStarVec2 end_vec2_original{};
//始点
AStarVec2 start_vec2{};
//終点
Expand All @@ -85,18 +89,20 @@ namespace paxs {
public:
AStar() noexcept = default;
AStar(const AStarVec2& start_vec2_, const AStarVec2& end_vec2_, const GridType z_) noexcept
:start_vec2(start_vec2_), end_vec2(end_vec2_), z(z_) {}
:start_vec2_original(start_vec2_), end_vec2_original(end_vec2_),
start_vec2(start_vec2_ / z_), end_vec2(end_vec2_ / z_),
z(z_) {}

constexpr GridType calculateDistance(const AStarVec2& vec2_) const noexcept {
const GridType x{ end_vec2.x - vec2_.x };
const GridType y{ end_vec2.y - vec2_.y };
return (x >= y) ? x : y;
}
constexpr bool isRange(const AStarVec2& vec2_) const noexcept {
return vec2_.x >= (std::min)(start_vec2.x, end_vec2.x)
&& vec2_.y >= (std::min)(start_vec2.y, end_vec2.y)
&& vec2_.x < (std::max)(start_vec2.x, end_vec2.x)
&& vec2_.y < (std::max)(start_vec2.y, end_vec2.y);
bool isRange(const AStarVec2& vec2_) const noexcept {
return vec2_.x >= (std::min)(start_vec2.x, end_vec2.x) - std::abs(start_vec2.x - end_vec2.x) / 2
&& vec2_.y >= (std::min)(start_vec2.y, end_vec2.y) - std::abs(start_vec2.y - end_vec2.y) / 2
&& vec2_.x < (std::max)(start_vec2.x, end_vec2.x) + std::abs(start_vec2.x - end_vec2.x) / 2
&& vec2_.y < (std::max)(start_vec2.y, end_vec2.y) + std::abs(start_vec2.y - end_vec2.y) / 2;
}

bool existPoint(const AStarVec2& vec2_, const double cost_) noexcept {
Expand Down Expand Up @@ -157,7 +163,7 @@ namespace paxs {

const AStarVec2 neighbour_z = neighbour * z;
if (!isRange(neighbour)) continue;
//if (!isRange(neighbour, x_, y_) || environment->getSlope(neighbour_z) >= 213) continue;
//if (!isRange(neighbour) || environment->getSlope(neighbour_z) >= 213) continue;
//コスト計算
const double node_cost = calcCost(environment, neighbour_z) + node_.cost;
const GridType distance = calculateDistance(neighbour);
Expand All @@ -182,18 +188,21 @@ namespace paxs {
return closed.back().cost;
}

double setPath(std::vector<AStarVec2>& path_) noexcept {
path_.emplace_back(end_vec2);
double cost{ 1 + closed.back().cost };
path_.emplace_back(closed.back().position);
void setPath(std::vector<AStarVec2>& path_) noexcept {
path_.resize(0);
const AStarVec2 sub = AStarVec2{
std::abs(start_vec2_original.x - start_vec2.x * z) / 2,
std::abs(start_vec2_original.y - start_vec2.y * z) / 2
};
// path_.emplace_back(end_vec2_original);
path_.emplace_back(closed.back().position * z + sub);
AStarVec2 parent_node{ closed.back().parent_node };
for (auto&& i{ closed.rbegin() }; i != closed.rend(); ++i) {
if (!((*i).position == parent_node) || ((*i).position == start_vec2)) continue;
path_.emplace_back((*i).position);
path_.emplace_back((*i).position * z + sub);
parent_node = (*i).parent_node;
}
path_.emplace_back(start_vec2);
return cost;
//path_.emplace_back(start_vec2_original);
}
};

Expand Down Expand Up @@ -251,12 +260,21 @@ namespace paxs {
/// @brief Set the position of the settlement.
/// @brief 集落の座標を設定
void setPosition(const Vector2& position_) noexcept {
old_position = position;
position = position_;
}
/// @brief
/// @brief 集落の過去の座標を消去
void clearOldPosition() noexcept {
old_position = Vector2(-1, -1);
positions.resize(0);
}

/// @brief Get the position of the settlement.
/// @brief 集落の座標を取得
Vector2 getPosition() const noexcept { return position; }
Vector2 getOldPosition() const noexcept { return old_position; }
const std::vector<Vector2>& getPositions() const noexcept { return positions; }

/// @brief Get the agent.
/// @brief エージェントを取得
Expand Down Expand Up @@ -520,12 +538,14 @@ namespace paxs {
if (cp_cw == mp_cw) break; // 同じ座標なので AStar 不可能
// 隣接座標なので AStar 不可能
else if (std::abs(cp_cw.x - mp_cw.x) <= 1 && std::abs(cp_cw.y - mp_cw.y) <= 1) break;
AStar astar(cp_cw, mp_cw, cw);
AStar astar(current_position, move_position, cw);
astar.search(environment);
// 最初の場合または以前よりもコストが低い場合は上書きする
if (cost == -1.0 || cost > astar.getCost()) {
target_position = move_position;
cost = astar.getCost();
// 経路を設定
astar.setPath(positions);
}
}
}
Expand Down Expand Up @@ -662,6 +682,8 @@ namespace paxs {
std::uint_least32_t id = 0;
/// @brief 集落の座標
Vector2 position{};
Vector2 old_position{ -1,-1 };
std::vector<Vector2> positions{};

std::mt19937* gen{}; // 乱数生成器

Expand Down
3 changes: 3 additions & 0 deletions Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,9 @@ namespace paxs {
for (auto& settlement_grid : settlement_grids) {
std::vector<Settlement>& settlements = settlement_grid.second.getSettlements();
for (std::size_t i = 0; i < settlements.size(); ++i) {
// 集落の過去の位置情報を削除
settlements[i].clearOldPosition();

if (settlements[i].isMoved()) {
continue;
}
Expand Down

0 comments on commit 0475d42

Please sign in to comment.