From 33736d3d11644f452288a54939499374aff2e54b Mon Sep 17 00:00:00 2001 From: wanotaitei Date: Sun, 17 Nov 2024 22:14:27 +0900 Subject: [PATCH 1/4] upd: simulation line --- Library/PAX_MAHOROBA/LocationPoint.hpp | 155 ++++++++++++++++-- Library/PAX_MAHOROBA/MapViewer.hpp | 2 +- Library/PAX_SAPIENTICA/Simulation/Data.hpp | 4 +- .../PAX_SAPIENTICA/Simulation/Settlement.hpp | 11 +- .../Simulation/SettlementSimulator.hpp | 12 +- .../Simulation/SimulationConst.hpp | 5 + 6 files changed, 171 insertions(+), 18 deletions(-) diff --git a/Library/PAX_MAHOROBA/LocationPoint.hpp b/Library/PAX_MAHOROBA/LocationPoint.hpp index 1afdba5fc..36c66fdc8 100644 --- a/Library/PAX_MAHOROBA/LocationPoint.hpp +++ b/Library/PAX_MAHOROBA/LocationPoint.hpp @@ -32,6 +32,7 @@ #include #include +#include #include #include #include @@ -556,6 +557,8 @@ namespace paxs { class AgentLocation { private: std::size_t select_draw = 1; + // 線を表示するか + bool is_line = false; #ifdef PAXS_USING_SIV3D // 選択肢を表示するフォント const s3d::Font select_font{ 30, s3d::Typeface::Bold }; @@ -701,6 +704,7 @@ namespace paxs { void draw(const double jdn, std::unordered_map& agents, + const std::vector& marriage_pos_list, const double map_view_width, const double map_view_height, const double map_view_center_x, const double map_view_center_y )/*const Siv3D Key は非 const */ { @@ -710,6 +714,8 @@ namespace paxs { else if (s3d::Key3.pressed()) select_draw = 3; else if (s3d::Key4.pressed()) select_draw = 4; else if (s3d::Key5.pressed()) select_draw = 5; + // グリッド線を描画する + else if (s3d::KeyL.up()) is_line = (!is_line); #endif // 地名を描画 @@ -720,12 +726,8 @@ namespace paxs { std::unordered_map < std::uint_least32_t, std::string>(), paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), paxs::Vector2( - settlement.getPosition().x, - settlement.getPosition().y - ) - , 10)), + settlement.getPosition().x,settlement.getPosition().y), 10)), 1, 1, 10, 100,0,0,99999999, - //(agent.getGender()) ? MurMur3::calcHash("agent1") ,0 /* 出典なし */ ,1.0 // 拡大率 @@ -738,10 +740,7 @@ namespace paxs { || lli.coordinate.y >(map_view_center_y + map_view_height / 1.6)) continue; // 範囲内の場合 - if (lli.min_view > map_view_height - || lli.max_view < map_view_height - || lli.min_year > jdn - || lli.max_year < jdn) { + if (lli.min_view > map_view_height || lli.max_view < map_view_height || lli.min_year > jdn || lli.max_year < jdn) { if (lli.min_year > jdn) continue; if (lli.max_year < jdn) continue; @@ -806,7 +805,97 @@ namespace paxs { ).draw(language_color); } + } + } + } #ifdef PAXS_USING_SIV3D + // グリッド線を描画 + if (is_line) { + const auto area_width = SimulationConstants::getInstance()->getEndArea().x - SimulationConstants::getInstance()->getStartArea().x; + const auto area_height = SimulationConstants::getInstance()->getEndArea().y - SimulationConstants::getInstance()->getStartArea().y; + + const paxs::MercatorDeg start_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2(0, 0), 10)); + const paxg::Vec2f draw_start_pos = paxg::Vec2f{ + static_cast((start_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())), + static_cast(double(paxg::Window::height()) - ((start_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) + }; + const paxs::MercatorDeg end_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2(area_width * 256, area_height * 256), 10)); + const paxg::Vec2f draw_end_pos = paxg::Vec2f{ + static_cast((end_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())), + static_cast(double(paxg::Window::height()) - ((end_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) + }; + const paxs::MercatorDeg tile_coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2(SimulationConstants::getInstance()->cell_group_length, SimulationConstants::getInstance()->cell_group_length), 10)); + const paxg::Vec2f tile_pos = paxg::Vec2f{ + static_cast((tile_coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())) - draw_start_pos.x(), + static_cast(double(paxg::Window::height()) - ((tile_coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) - draw_start_pos.y() + }; + + paxg::Line( + static_cast(draw_start_pos.x()), static_cast(draw_start_pos.y()), + static_cast(draw_start_pos.x()), static_cast(draw_end_pos.y()) + ).draw(5, paxg::Color(0, 0, 0)); + paxg::Line( + static_cast(draw_start_pos.x()), static_cast(draw_start_pos.y()), + static_cast(draw_end_pos.x()), static_cast(draw_start_pos.y()) + ).draw(5, paxg::Color(0, 0, 0)); + paxg::Line( + static_cast(draw_end_pos.x()), static_cast(draw_start_pos.y()), + static_cast(draw_end_pos.x()), static_cast(draw_end_pos.y()) + ).draw(5, paxg::Color(0, 0, 0)); + paxg::Line( + static_cast(draw_start_pos.x()), static_cast(draw_end_pos.y()), + static_cast(draw_end_pos.x()), static_cast(draw_end_pos.y()) + ).draw(5, paxg::Color(0, 0, 0)); + + for (float i = draw_start_pos.x(); i < draw_end_pos.x(); i += tile_pos.x()) { + paxg::Line( + static_cast(i), static_cast(draw_start_pos.y()), + static_cast(i), static_cast(draw_end_pos.y()) + ).draw(0.5, paxg::Color(0, 0, 0)); + } + for (float i = draw_start_pos.y(); i < draw_end_pos.y(); i += tile_pos.y()) { + paxg::Line( + static_cast(draw_start_pos.x()), static_cast(i), + static_cast(draw_end_pos.x()), static_cast(i) + ).draw(0.5, paxg::Color(0, 0, 0)); + } + } + + // 移動線を描画 + for (const auto& agent : agents) { + for (const auto& settlement : agent.second.cgetSettlements()) { + // エージェントの初期設定を定義 + const auto lli = LocationPoint{ + std::unordered_map < std::uint_least32_t, std::string>(), + paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2( + settlement.getPosition().x,settlement.getPosition().y), 10)), + 1, 1, 10, 100,0,0,99999999, + MurMur3::calcHash("agent1") + ,0 /* 出典なし */ + ,1.0 // 拡大率 + }; + + // 経緯度の範囲外を除去 + if (lli.coordinate.x < (map_view_center_x - map_view_width / 1.6) + || lli.coordinate.x >(map_view_center_x + map_view_width / 1.6) + || lli.coordinate.y < (map_view_center_y - map_view_height / 1.6) + || lli.coordinate.y >(map_view_center_y + map_view_height / 1.6)) continue; + + // 範囲内の場合 + if (lli.min_view > map_view_height || lli.max_view < map_view_height || lli.min_year > jdn || lli.max_year < jdn) { + if (lli.min_year > jdn) continue; + if (lli.max_year < jdn) continue; + + // 描画位置 + const paxg::Vec2i draw_pos = paxg::Vec2i{ + static_cast((lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())), + static_cast(double(paxg::Window::height()) - ((lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) + }; + if (settlement.getOldPosition().x != -1 && settlement.getOldPosition().x != 0) { if (settlement.getPositions().size() >= 1) { @@ -864,12 +953,58 @@ namespace paxs { 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 } } } + // 移動線を描画 + for (const auto& marriage_pos : marriage_pos_list) { + // エージェントの初期設定を定義 + const auto lli = LocationPoint{ + std::unordered_map < std::uint_least32_t, std::string>(), + paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2( + marriage_pos.ex,marriage_pos.ey), 10)), + 1, 1, 10, 100,0,0,99999999, + MurMur3::calcHash("agent1") + ,0 /* 出典なし */ + ,1.0 // 拡大率 + }; + + // 経緯度の範囲外を除去 + if (lli.coordinate.x < (map_view_center_x - map_view_width / 1.6) + || lli.coordinate.x >(map_view_center_x + map_view_width / 1.6) + || lli.coordinate.y < (map_view_center_y - map_view_height / 1.6) + || lli.coordinate.y >(map_view_center_y + map_view_height / 1.6)) continue; + + // 範囲内の場合 + if (lli.min_view > map_view_height || lli.max_view < map_view_height || lli.min_year > jdn || lli.max_year < jdn) { + if (lli.min_year > jdn) continue; + if (lli.max_year < jdn) continue; + + // 描画位置 + const paxg::Vec2i draw_pos = paxg::Vec2i{ +static_cast((lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())), + static_cast(double(paxg::Window::height()) - ((lli.coordinate.y - (map_view_center_y - map_view_height / 2)) / map_view_height * double(paxg::Window::height()))) + }; + + if (marriage_pos.sx != -1 && marriage_pos.sx != 0) { + // 過去の位置 + auto old_lli = lli; + old_lli.coordinate = paxs::MercatorDeg(getLocation(SimulationConstants::getInstance()->getStartArea(), + paxs::Vector2( + marriage_pos.sx, + marriage_pos.sy), 10)); + const paxg::Vec2i draw_old_pos = paxg::Vec2i{ +static_cast((old_lli.coordinate.x - (map_view_center_x - map_view_width / 2)) / map_view_width * double(paxg::Window::width())), + static_cast(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::Color(221, 67, 98)); + } + } + } +#endif } }; diff --git a/Library/PAX_MAHOROBA/MapViewer.hpp b/Library/PAX_MAHOROBA/MapViewer.hpp index 4bdc83b8a..702c8dce0 100644 --- a/Library/PAX_MAHOROBA/MapViewer.hpp +++ b/Library/PAX_MAHOROBA/MapViewer.hpp @@ -105,7 +105,7 @@ namespace paxs { #ifdef PAXS_USING_SIMULATOR if (visible[MurMur3::calcHash("Simulation")]) { if (agent_location.get() != nullptr && simulator.get() != nullptr) { - agent_location->draw(koyomi_siv.jdn.cgetDay(), simulator->getSettlementGrids(), map_view.getWidth(), map_view.getHeight(), map_view.getCenterX(), map_view.getCenterY() + agent_location->draw(koyomi_siv.jdn.cgetDay(), simulator->getSettlementGrids(), simulator->getMarriagePosList(), map_view.getWidth(), map_view.getHeight(), map_view.getCenterX(), map_view.getCenterY() ); } } diff --git a/Library/PAX_SAPIENTICA/Simulation/Data.hpp b/Library/PAX_SAPIENTICA/Simulation/Data.hpp index 5406c37e7..cbebfe38d 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Data.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Data.hpp @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include #include @@ -96,7 +96,7 @@ namespace paxs { private: std::string name; // データの名前 - std::unordered_map data; // データ + std::map data; // データ int default_z; // データのz値 double z_mag; // シミュレーションのz値からデータのz値に変換するときの倍率 int column_size; // シミュレーションの列数 diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index 78862db43..1fc77bb2e 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -334,9 +334,12 @@ namespace paxs { /// @brief Marriage. /// @brief 婚姻 + template void marriage(std::vector close_settlements, - std::function add_agent, - std::function delete_agent + //std::function add_agent, + //std::function delete_agent, + Add_&& add_agent, Delete_&& delete_agent, + std::vector& marriage_pos_list ) noexcept { // 結婚の条件を満たすエージェントを取得 std::vector marriageable_female_index; @@ -442,6 +445,8 @@ namespace paxs { male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer(), female_.cgetLanguage()); agents.emplace_back(male_); + + marriage_pos_list.emplace_back(close_settlements[j]->position.x, close_settlements[j]->position.y, position.x, position.y); } // 父方の場合 else { @@ -455,6 +460,8 @@ namespace paxs { male_settlement_position /= SimulationConstants::getInstance()->cell_group_length; add_agent(female_, male_settlement_id, male_settlement_position); + + marriage_pos_list.emplace_back(position.x, position.y, close_settlements[j]->position.x, close_settlements[j]->position.y); } is_found = true; break; diff --git a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp index cc307d94a..eaf6c5a48 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SettlementSimulator.hpp @@ -285,8 +285,9 @@ namespace paxs { } m_start_time = std::chrono::system_clock::now(); // 婚姻計測開始 + marriage_pos_list.clear(); - auto delete_agent = [this](const std::uint_least32_t agent_id, const std::uint_least32_t settlement_id, const Vector2 key) { + auto&& delete_agent = [this](const std::uint_least32_t agent_id, const std::uint_least32_t settlement_id, const Vector2 key) { auto it = settlement_grids.find(key.to(SettlementGridsType{})); if (it != settlement_grids.end()) { it->second.deleteAgent(agent_id, settlement_id); @@ -296,7 +297,7 @@ namespace paxs { } }; - auto add_agent = [this](const paxs::SettlementAgent agent_, const std::uint_least32_t settlement_id, const Vector2 key) { + auto&& add_agent = [this](const paxs::SettlementAgent agent_, const std::uint_least32_t settlement_id, const Vector2 key) { auto it = settlement_grids.find(key.to(SettlementGridsType{})); if (it != settlement_grids.end()) { it->second.addAgent(agent_, settlement_id); @@ -328,7 +329,7 @@ namespace paxs { } for (auto& settlement : settlements) { - settlement.marriage(close_settlements, add_agent, delete_agent); + settlement.marriage(close_settlements, add_agent, delete_agent, marriage_pos_list); } } @@ -363,6 +364,9 @@ namespace paxs { processing_time = static_cast(std::chrono::duration_cast(end_time - start_time).count() / 1000.0); } + // 婚姻時に移動した位置一覧を取得する + const std::vector& getMarriagePosList() const { return marriage_pos_list; } + /// @brief Get the agent list. /// @brief エージェントのリストを取得する constexpr std::unordered_map& @@ -426,6 +430,8 @@ namespace paxs { std::ofstream snp_ofs; std::ofstream language_ofs; std::ofstream live_ofs; + // 婚姻時に移動前の位置と移動後の位置を記録 + std::vector marriage_pos_list{}; /// @brief () /// @brief 集落をランダムに配置する前の初期化処理 diff --git a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp index d02b0ec87..304b3914f 100644 --- a/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/SimulationConst.hpp @@ -58,6 +58,11 @@ namespace paxs { constexpr std::array , 8> astar_adjacent_cell{ {Vector2(-1, -1),Vector2(1, -1),Vector2(-1, 1),Vector2(1, 1),Vector2(0, -1),Vector2(-1, 0),Vector2(0, 1),Vector2(1, 0)} }; + // 始点と終点を管理(婚姻の前後の位置情報を保持する用) + struct GridType4 { + GridType sx{}, sy{}, ex{}, ey{}; + }; + struct SimulationConstants { // インスタンスを取得 static SimulationConstants* getInstance() { From 821f7e9f93a096ae401c0267fab0103b6dfc1c70 Mon Sep 17 00:00:00 2001 From: wanotaitei Date: Sun, 17 Nov 2024 22:22:37 +0900 Subject: [PATCH 2/4] fix: function copy --- Library/PAX_SAPIENTICA/Simulation/Settlement.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index 1fc77bb2e..b8b8621f1 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -338,7 +338,7 @@ namespace paxs { void marriage(std::vector close_settlements, //std::function add_agent, //std::function delete_agent, - Add_&& add_agent, Delete_&& delete_agent, + Add_ add_agent, Delete_ delete_agent, std::vector& marriage_pos_list ) noexcept { // 結婚の条件を満たすエージェントを取得 From 55c92c16a31817b13a79545b8d3a1f6d601e67d7 Mon Sep 17 00:00:00 2001 From: wanotaitei Date: Sun, 17 Nov 2024 22:25:52 +0900 Subject: [PATCH 3/4] fix: returned function --- Library/PAX_SAPIENTICA/Simulation/Settlement.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index b8b8621f1..c4d770c12 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -334,11 +334,11 @@ namespace paxs { /// @brief Marriage. /// @brief 婚姻 - template + //template void marriage(std::vector close_settlements, - //std::function add_agent, - //std::function delete_agent, - Add_ add_agent, Delete_ delete_agent, + std::function add_agent, + std::function delete_agent, + //Add_ add_agent, Delete_ delete_agent, std::vector& marriage_pos_list ) noexcept { // 結婚の条件を満たすエージェントを取得 From 3433ded46dbab87bc91d72445adf075b92373d79 Mon Sep 17 00:00:00 2001 From: wanotaitei Date: Sun, 17 Nov 2024 22:32:43 +0900 Subject: [PATCH 4/4] fix: std::vector --- Library/PAX_SAPIENTICA/Simulation/Settlement.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp index c4d770c12..cf14e51b5 100644 --- a/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp +++ b/Library/PAX_SAPIENTICA/Simulation/Settlement.hpp @@ -446,7 +446,7 @@ namespace paxs { male_.marry(female_id, female_.cgetGenome(), female_.cgetFarming(), female_.cgetHunterGatherer(), female_.cgetLanguage()); agents.emplace_back(male_); - marriage_pos_list.emplace_back(close_settlements[j]->position.x, close_settlements[j]->position.y, position.x, position.y); + marriage_pos_list.emplace_back(GridType4{ close_settlements[j]->position.x, close_settlements[j]->position.y, position.x, position.y }); } // 父方の場合 else { @@ -461,7 +461,7 @@ namespace paxs { male_settlement_position /= SimulationConstants::getInstance()->cell_group_length; add_agent(female_, male_settlement_id, male_settlement_position); - marriage_pos_list.emplace_back(position.x, position.y, close_settlements[j]->position.x, close_settlements[j]->position.y); + marriage_pos_list.emplace_back(GridType4{ position.x, position.y, close_settlements[j]->position.x, close_settlements[j]->position.y }); } is_found = true; break;