Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

移動経路を矢印で可視化する機能を追加 #108

Merged
merged 1 commit into from
Oct 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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