提示コード最上部のcrosss_pos()関数部の戻り値ですがreturn new Position();をしてしまっていてこのコードは悪いコードだと思います。
しかしながら当たっているときは衝突座標を返して当たっていないときはNULLや無効な値を返したいと思うのですがなにかいい方法はあるのでしょうか? 0だと0に補正するという場合に困るので避けたいです。
/*-----------------------------------衝突座標を返す関数-----------------------------------------*/ //std::optional<Position> cross_pos(Position a, Position b, Position c, Position d) Position* cross_pos(Position a, Position b, Position c, Position d) { /*線分の交差か平行か判定*/ //tc = (x1 - x2) * (y3 - y1) + (y1 - y2)* (x1 - x3); float tc = (a.x - b.x) * (c.y - a.y) + (a.y - b.y) * (a.x - c.x); //td = (x1 - x2) * (y4 - y1) + (y1 - y2)* (x1 - x4); float td = (a.x - b.x) * (d.y - a.y) + (a.y - b.y) * (a.x - d.x); //ta = (x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1) float ta = (c.x - d.x) * (a.y - c.y) + (c.y - d.y) * (c.x - a.x); //tb = (x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2) float tb = (c.x - d.x) * (b.y - c.y) + (c.y - d.y) * (c.x - b.x); Position ab, ac, bc, bd, ad, cd, cb, db, ca; /*線分を取得*/ ab = Position(b.x - a.x, b.y - a.y); ad = Position(d.x - a.x, d.y - a.y); ac = Position(c.x - a.x, c.y - a.y); bc = Position(c.x - b.x, c.y - b.y); cb = Position(b.x - c.x, b.y - c.y); bd = Position(d.x - b.x, d.y - b.y); cd = Position(d.x - c.x, d.y - c.y); db = Position(b.x - d.x, b.y - d.y); ca = Position(a.x - c.x, a.y - c.y); /*外積を使ってスカラーを取得*/ float BD_AB = (bd.x * ab.y) - (ab.x * bd.y); float CB_DB = (cb.x * bd.y) - (bd.x * cb.y); float BD_BC = (bd.x * bc.y) - (bc.x * bd.y); float AD_CD = (ad.x * cd.y) - (cd.x * ad.y); float BC_BD = (bd.x * bc.y) - (bc.x * bd.y); float BD_AD = (ad.x * bd.y) - (bd.x * ad.y); float AB_AC = (ac.x * ab.y) - (ac.x * ab.y); float AB_AD = (ad.x * ab.y) - (ad.x * ab.y); printf("ta: %f\n", ta); printf("tb: %f\n", tb); printf("tc: %f\n", tc); printf("td: %f\n", td); /*線分の交差判定 平行はfalse*/ if (tc * td < 0 && ta * tb < 0) { /*比率*/ float k = AD_CD / (AD_CD + CB_DB); float x = a.x + k * (b.x - a.x); float y = a.y + k * (b.y - a.y); // printf("交差している。\n"); printf("x: %f\n", x); printf("y: %f\n", y); //return 交差座標 //return Position(x, y); return new Position(x, y); } else { Position acV(c.x - a.x, c.y - a.y);//線分の始点Aと判定するCのベクトルを設定 Position abV(b.x - a.x, b.y - a.y);//線分の始点Aと判定するDのベクトルを設定 Position caV(a.x - c.x, a.y - c.y);//線分の始点Cと判定するAのベクトルを設定 Position cbV(b.x - c.x, b.y - c.y);//線分の始点Cと判定するBのベクトルを設定 //(x1-x0)*(x2-x0) + (y1-y0)*(y2-y0) //x1終点 x0 始点 2 点 float CV = (b.x - a.x) * (c.x - a.x) + (b.y - a.y) * (c.y - a.y); float DV = (b.x - a.x) * (d.x - a.x) + (b.y - a.y) * (d.y - a.y); float AV = (d.x - c.x) * (a.x - c.x) + (d.y - c.y) * (a.y - c.y); float BV = (d.x - c.x) * (b.x - c.x) + (d.y - c.y) * (b.y - c.y); float rangeAB = sqrt((ab.y * ab.y) + (ab.x * ab.x));//A -> Bの長さ float rangeAC = sqrt((ac.y * ac.y) + (ac.x * ac.x));//ACの距離 float rangeAD = sqrt((ad.y * ad.y) + (ad.x * ad.x));//ADの距離 float rangeCD = sqrt((cd.y * cd.y) + (cd.x * cd.x));//C -> Dの長さ float rangeCA = sqrt((ca.y * ca.y) + (ca.x * ca.x));//CAの距離 float rangeCB = sqrt((cb.y * cb.y) + (cb.x * cb.x));//CDの距離 printf("CV: %f\n", CV); printf("DV: %f\n", DV); //C D の線分がABの線分の上に居る。 if ((CV == (rangeAB * rangeAC) && rangeAB >= rangeAC) && (DV == (rangeAB * rangeAD) && rangeAB >= rangeAD)) { if (CV < DV) { // return Position(c.x, c.y); return new Position(c.x, c.y); } else { return new Position(d.x, d.y); } printf("C D が線分の上にある。\n"); } else if (CV == (rangeAB * rangeAC) && rangeAB >= rangeAC) { printf("C が線分上にある。\n"); return new Position(c.x, c.y); } else if ((DV == (rangeAB * rangeAD) && rangeAB >= rangeAD)) { printf("D が線分上にある。\n"); return new Position(d.x, d.y); } else { /*-----------------------------------CD線分上にA,Bがあるかどうかを判定-----------------------------------------*/ printf("ABがCD線分上に居るか判定\n"); // if ((CV == (rangeAB * rangeAC) && rangeAB >= rangeAC) && (DV == (rangeAB * rangeAD) && rangeAB >= rangeAD)) if ((AV == (rangeCD * rangeCA) && rangeCD >= rangeCA) && (BV == (rangeCD * rangeCB) && rangeCD >= rangeCB)) { if (AV < BV) { return new Position(a.x, a.y); } else { return new Position(b.x, b.y); } printf("A B が線分の上にある。\n"); } else if (AV == (rangeCD * rangeCA) && rangeCD >= rangeCA) { printf("A が線分上にある。\n"); return new Position(a.x, a.y); } else if (BV == (rangeCD * rangeCB) && rangeCD >= rangeCB) { printf("b が線分上にある。\n"); return new Position(b.x, b.y); } } } // return std::nullopt; return NULL;//衝突してない時 } /* a の 向きを取得 プラスが← マイナスが右 */ int cross_direction(Position a, Position b, Position c, Position d) { /*線分の交差か平行か判定*/ //tc = (x1 - x2) * (y3 - y1) + (y1 - y2)* (x1 - x3); float tc = (a.x - b.x) * (c.y - a.y) + (a.y - b.y) * (a.x - c.x); //td = (x1 - x2) * (y4 - y1) + (y1 - y2)* (x1 - x4); float td = (a.x - b.x) * (d.y - a.y) + (a.y - b.y) * (a.x - d.x); //ta = (x3 - x4) * (y1 - y3) + (y3 - y4) * (x3 - x1) float ta = (c.x - d.x) * (a.y - c.y) + (c.y - d.y) * (c.x - a.x); //tb = (x3 - x4) * (y2 - y3) + (y3 - y4) * (x3 - x2) float tb = (c.x - d.x) * (b.y - c.y) + (c.y - d.y) * (c.x - b.x); if(ta < 0) { return -1; }else if(ta > 0){ return 1; } } bool b = false; /*---------------------------------------------------当たり判定----------------------------------------------------------------*/ void Collision_Update() { // std::unique_ptr<Position> xPlayer_up, xPlayer_down; // std::unique_ptr<Position> yPlayer_left, yPlayer_right; Position *xPlayer_up, *xPlayer_down; Position *yPlayer_left, *yPlayer_right; xPlayer_up = NULL; xPlayer_down = NULL; yPlayer_left = NULL; yPlayer_right = NULL; bool xR ,xL; xR = xL = false; Position now_x[2];//今いる座標 Position now_y[2];//今いる座標 Position future_x[2];//移動先 座標 Position future_y[2];//移動先 座標 now_x[0].x = pos->x + ((CELL) / 2); now_x[0].y = pos->y; now_x[1].x = pos->x + ((CELL) / 2); now_x[1].y = pos->y + (CELL); now_y[0].x = pos->x + ((CELL) / 2); now_y[0].y = pos->y + ((CELL) / 2); now_y[1].x = pos->x + ((CELL) / 2); now_y[1].y = pos->y + ((CELL) / 2); /*未来座標配列に現在座標をコピーする*/ future_x[0].x = now_x[0].x + move->x; future_x[0].y = now_x[0].y + move->y; future_x[1].x = now_x[1].x + move->x; future_x[1].y = now_x[1].y + move->y; future_y[0].x = now_y[0].x + move->x; future_y[0].y = now_y[0].y + move->y; future_y[1].x = now_y[1].x + move->x; future_y[1].y = now_y[1].y + move->y; for(int y = 0; y < 100; y++){ for(int x = 0;x < 100; x++){ if(Find_Map(x,y) == true){ // ofs<<"x y: "<<x <<" , "<<y<<std::endl; Position *u = NULL ,*d = NULL; u = cross_pos(now_x[0], future_x[0], Position(x * CELL + (CELL / 2), y * CELL), Position((x * CELL) + (CELL / 2), ((y + 1) * CELL))); if(u != NULL) { xPlayer_up = u; ofs<<"x: "<<xPlayer_up->x<<std::endl; } d = cross_pos(now_x[1], future_x[1], Position(x * CELL + (CELL / 2), y * CELL), Position((x * CELL) + (CELL / 2), ((y + 1) * CELL))); if(d != NULL) { xPlayer_down = d; } } } } /*→に移動するときの補正*/ if (Direction->x > 0) { /*上と下の当たった時の長さ 短いほうに補正する*/ ofs << "→ 移動" << std::endl; float up,down; up = down = -1; if(xPlayer_up != NULL){ up = xPlayer_up->x; up = up - (CELL + (CELL / 2)); ofs << "up: " << up << std::endl; } if (xPlayer_down != NULL) { down = xPlayer_down->x; down = down - (CELL + (CELL / 2)); ofs << "down: " << down << std::endl; } if( (down == -1) && (up > -1) ) { pos->x = up; }else if( (down > -1) && (up == -1) ) { pos->x = down; }else if( (down != -1 && up != -1) )//両方のが当たっている場合 { if(down >= up) { pos->x = up; }else{ pos->x = down; } } /**/ if((xPlayer_down == NULL) && (xPlayer_up == NULL)) { //pos->x = future_x[0].x; pos->x += move->x; } } /*←に移動するときの補正*/ if(Direction->x < 0) { /*上と下の当たった時の長さ 短いほうに補正する*/ ofs << "← 移動" << std::endl; float up, down; up = down = 1; if (xPlayer_up != NULL) { up = xPlayer_up->x; up = up + (CELL / 2); ofs << "up: " << up << std::endl; } if (xPlayer_down != NULL) { down = xPlayer_down->x; down = down + (CELL / 2); ofs << "down: " << down << std::endl; } if ((down == 1) && (up > 1)) { pos->x = up; } else if ((down > 1) && (up == 1)) { pos->x = down; } else if ((down != 1 && up != 1))//両方のが当たっている場合 { if (down >= up) { pos->x = down; } else { pos->x = up; } } /**/ if ((xPlayer_down == NULL) && (xPlayer_up == NULL)) { //pos->x = future_x[0].x; pos->x += move->x; } } } /*-------------------------------------------------------------------------------------------------------------------------*/
回答4件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2019/12/30 09:45
2019/12/31 08:55