提示コードですが線分の円の当たり判定が実装出来ません、デバッグしたところによるよ常にstd::cout<<"(dot01 * dot02) <= 0.0f"<<std::endl;
が成立しているみたいで常に交差しているみたいです。これはなぜなのでしょうか?参考サイトを参考にコードを入力したのですが③では②の結果と円の半径を比較します。
部のあたりからif()
文に内部なのか外に追記するのかわかりません。また他の部分をも確認しましたが問題ないです。
Console Log
shigurechan@shigurechan-System-Product-Name:~/Program/SDLGame/libTest$ sh run.sh g++ -c -MMD -MP src/Player.cpp -o obj/Player.o g++ -c -MMD -MP ../lib/src/Collision.cpp -o ../lib/obj/Collision.o ar rcs ../lib/libSDLGame.a ../lib/obj/Circle_Collision.o ../lib/obj/Circle_Render.o ../lib/obj/Collision.o ../lib/obj/Component.o ../lib/obj/GameObject.o ../lib/obj/Line_Collision.o ../lib/obj/Line_Render.o ../lib/obj/Rectangle_Collision.o ../lib/obj/Rectangle_Render.o ../lib/obj/SDLGame.o ../lib/obj/Sprite_Render.o ../lib/obj/Transform.o ../lib/obj/Circle_Collision.o ../lib/obj/Circle_Render.o ../lib/obj/Collision.o ../lib/obj/Component.o ../lib/obj/GameObject.o ../lib/obj/Line_Collision.o ../lib/obj/Line_Render.o ../lib/obj/Rectangle_Collision.o ../lib/obj/Rectangle_Render.o ../lib/obj/SDLGame.o ../lib/obj/Sprite_Render.o ../lib/obj/Transform.o g++ obj/Enemy.o obj/Game.o obj/Main.o obj/Player.o -o program ../lib/libSDLGame.a -lSDL2main -lSDL2 -lSDL2_image (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <= 0.0f (dot01 * dot02) <=
Collison
cpp
1 2 3bool SDL::LineAndCircle_Collision_Hit(const glm::vec2 start,const glm::vec2 end,const glm::vec2 center,const float range) 4{ 5 glm::vec2 start_center = center - start; 6 glm::vec2 end_center = center - end; 7 glm::vec2 end_start = end - start; 8 9 glm::vec2 norm = glm::normalize(end_start); 10 11 float r = end_start.x * norm.y - end_start.y * norm.x; 12 13 14 if(r < range) 15 { 16 float dot01 = start_center.x * end_start.x + start_center.y * end_start.y; 17 float dot02 = end_center.x * end_start.x + end_center.y * end_start.y; 18 19 // 二つの内積の掛け算結果が0以下なら当たり 20 if ( (dot01 * dot02) <= 0.0f ) 21 { 22 std::cout<<"(dot01 * dot02) <= 0.0f"<<std::endl; 23 return true; 24 25 } 26 27 if( (end_center.length() < range) || (start_center.length() < range) ) 28 { 29 std::cout<<"(end_center.length() < range) || (start_center.length() < range)"<<std::endl; 30 31 return true; 32 } 33 34 } 35 36 return false; 37 38} 39
Player.cpp
cpp
1#include "Player.hpp" 2 3#include "../../lib/src/SDLGame.hpp" 4//#include "../../lib/src/BoxCollision.hpp" 5 6#include <iostream> 7#include <memory> 8 9/*################################################# 10# 初期化 11###################################################*/ 12Player::Player() : GameObject() 13{ 14 transform.position = glm::vec2((SDL::GetWindowSize().x / 2) - 50 - 200,(SDL::GetWindowSize().y / 2) - 50); 15 16 lineCollision = std::make_shared<SDL::Line_Collision>(); 17 lineCollision->startPosition = transform.position; 18 lineCollision->endPosition = transform.position + glm::vec2(100,100); 19 20 lineRender = std::make_shared<SDL::Line_Render>(); 21 lineRender->startPosition = transform.position; 22 lineRender->endPosition = transform.position + glm::vec2(100,100); 23 24 lineRender->color = glm::vec4(255,255,255,255); 25 26 27} 28 29/*################################################# 30# 更新 31###################################################*/ 32void Player::Update() 33{ 34 Input(); 35 36 lineRender->startPosition = transform.position; 37 lineRender->endPosition = transform.position + glm::vec2(100,100); 38 39 40 lineCollision->startPosition = transform.position; 41 lineCollision->endPosition = transform.position + glm::vec2(100,100); 42 43} 44 45void Player::Collision(const std::shared_ptr<SDL::GameObject> obj) 46{ 47 48 49 if(lineCollision->getHitEnter(obj->circleCollision) == true) 50 { 51 std::cout<<"Enter"<<std::endl; 52 } 53 54 55/* 56 if(lineCollision->getHitStay(obj->circleCollision) == true) 57 { 58 std::cout<<"Stay"<<std::endl; 59 } 60 61 62 if(lineCollision->getHitExit(obj->circleCollision) == true) 63 { 64 std::cout<<"Exit"<<std::endl; 65 } 66*/ 67 68} 69 70/*################################################# 71# 描画 72###################################################*/ 73 74void Player::Render() const 75{ 76 lineRender->Render(); 77 78} 79
Enemy
cpp
1#include "Enemy.hpp" 2#include "../../lib/src/SDLGame.hpp" 3 4 5/*################################################# 6# 初期化 7###################################################*/ 8Enemy::Enemy() : SDL::GameObject() 9{ 10 transform.position = glm::vec2((SDL::GetWindowSize().x / 2) - 50,(SDL::GetWindowSize().y / 2) - 50); 11 12 circleCollision = std::make_shared<SDL::Circle_Collision>(); 13 circleCollision->position = transform.position; 14 circleCollision->range = 60.0f; 15 16 17 circleRender = std::make_shared<SDL::Circle_Render>(); 18 circleRender->transform.position = transform.position; 19 circleRender->range = 60.0f; 20 circleRender->color = glm::vec4(0,255,0,255); 21 22} 23 24/*################################################# 25# 更新 26###################################################*/ 27void Enemy::Update() 28{ 29 30// circleCollision->position = transform.position; 31 32 33} 34 35/*################################################# 36# 描画 37###################################################*/ 38void Enemy::Render()const 39{ 40 circleRender->Render(); 41} 42 43/*################################################# 44# 終了処理 45###################################################*/ 46Enemy::~Enemy() 47{ 48 49} 50
Game.cpp
cpp
1/*################################################# 2# 更新 3###################################################*/ 4void Game::Update() 5{ 6 for(std::vector<std::shared_ptr<SDL::GameObject>>::const_iterator itr = gameObject.begin(); itr != gameObject.end(); itr++) 7 { 8 (*itr)->Update(); 9 } 10 11 for(std::vector<std::shared_ptr<SDL::GameObject>>::const_iterator itr = gameObject.begin(); itr != gameObject.end(); itr++) 12 { 13 for(std::vector<std::shared_ptr<SDL::GameObject>>::const_iterator it = gameObject.begin(); it != gameObject.end(); it++) 14 { 15 if(it != itr) 16 { 17 (*itr)->Collision(*it); 18 } 19 } 20 } 21} 22
リンク先は「本当にたかだか円と線分の判定の話なのか?」っていうくらいに異様に長すぎて私はその内容を読む気もしないが…
> if()文に内部なのか外に追記するのかわかりません
…っていうなら,あなたは「そもそもそこの話の演算の内容を理解できていない」ってことでしょ?
そんな状態で実装に着手していること自体が間違っている.(偶然うまくいくことに賭けているの?)
そのリンク先の長文の内容があなたに合わないのであれば,別の方法の話を探すなり,自前で導出するなりした方が早いのではあるまいか.
リンク先をちょっと見ただけでやたら話がごちゃごちゃしているけど,
円 vs 線分 であれば
・線分上の点のうち,円の中心に最も近い点Pを求む
・円の中心から点Pまでの距離 と 円の半径 とを比較
っていうだけの話で済むんじゃないかなぁ.
(こういうのは座標群を最初に「一方の軸が線分と平行である座標系」の値に座標変換してから判定作業をするようなイメージで考ればわかりやすいんじゃないかな)
問題なのは SDL::LineAndCircle_Collision_Hit の挙動ですが、それ以外の部分は SDL::LineAndCircle_Collision_Hit を呼出してすらいないのでどのように関係するのかわかりません。
質問者にとっては関係しそうな部分を抽出したのかもしれませんが、質問を読む人はプログラムの全体像の知識を全く持っていないということを前提として繋がりが分かるように提示してください。
あるいは単に座標の計算の話ですからどのような座標が与えられたときに SDL::LineAndCircle_Collision_Hit が期待と違う挙動をするのか具体例の数値をいくつか提示するという形でもよいと思います。
> glm::vec2 norm = glm::normalize(end_start);
> float r = end_start.x * norm.y - end_start.y * norm.x;
これは一体どのような意図の演算なのであろうか?
r は理屈上常に 0 になると見えるが.
各段階の計算結果を見ていけば意図通りの値になっていない箇所はすぐに発見できると思うんですが、個々の値の意味が十分に理解できていないので正しいかどうかわからないということでしょうね。

回答2件
あなたの回答
tips
プレビュー