質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.91%

C++で二次元配列のソート

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 271

aiouongaku

score 1

実現したいこと

C++で作成しています。
PCD形式の点群データを配列に格納し,class内のデータ(二次元配列)でソートしたいです。(伝え方が難しい)
垂直角のソートは出来ているのですが,水平角のソート方法がわかりません.
解決策がありましたら教えていただきたいです.

該当のソースコード

/*Point.h*/

class Point{
public:
double x,y,z;      //点のx,y,z座標値
double hori_angle;   //xy平面上でのx軸と点の角度(以下、水平角)
double vertical_angle; //xy平面と点のなす角度(以下、垂直角)
Point();
};
/*Point.cpp*/

#include "Point.h"
Point::Point(){
}
/*main.cpp*/

using namespace pcl;
PointCloud<pcl::PointXYZI>::Ptr input(new pal::PointCloud<pcl::PointXYZI>);//入力点群

int hori = 7;    //水平方向データ数
int vertical = 4; //垂直方向データ数

Void main(void){
  for(int i = 0; i < hori; i++){
   for(int j = 0; j < vertical; j++){
     /*点群データを配列に格納*/
   a_point[j][i].x = input->points[i*4+j].x;
     a_point[j][i].y = input->points[i*4+j].y;
     a_point[j][i].z = input->points[i*4+j].z;

     /*垂直角・水平角を求める*/
     a_point[j][i].hori_angle = atan2(a_point[j][i].y,a_point[j][i].x);
     a_point[j][i].vertical_angle = /*計算式*/;
     //↑↑↑それぞれ[rad]から[deg]に変換,水平角は-180[deg]~180[deg]が,垂直角は-10[deg]~30[deg]が得られる
   }
  }
  /*並べ替える*/
  Sort();
}

Void Sort(void){

   /*水平角を-180[deg]から 昇順に並べた後 ,同じ水平角内で垂直角を-10[deg]から昇順に並べたい.
       理想形は以下のようになる.(このような表し方が正しいのかは多目に見て欲しいです)

    a_point[hori][vertical].hori_angle 
               = [-180,-180,-180,-180,-180,-180,-180],
                 [-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ],
                 [0   ,0   ,0   ,0   ,0   ,0   ,0   ],
                 [180 ,180 ,180 ,180 ,180 ,180 ,180 ];

       a_point[hori][vertical].vertical_angle 
               = [-10,0,10,15,20,25,30],
                 [-10,0,10,15,20,25,30],
                 [-10,0,10,15,20,25,30],
                 [-10,0,10,15,20,25,30];

*/
}

入力(ソート前)データ

a_point[ hori ][ vertical ].hori_angle = 
[-180,-180,0   ,-30 ,-30 ,0   ,-180],
[-30 ,0   ,0   ,-30 ,-180,180 ,0   ],
[0   ,0   ,-180,180 ,-180,-30 ,180 ],
[-180,-30 ,180 ,180 ,-30 ,180 ,180 ];

a_point[ hori ][ vertical ].vertical_angle = 
[-10 ,10  ,-10 ,0   ,15  ,10  ,30  ],
[-10 ,30  ,20  ,25  ,15  ,10  ,0   ],
[15  ,25  ,0   ,25  ,25  ,20  ,30  ],
[20  ,10  ,-10 ,20  ,30  ,0   ,15  ];

1.水平角ソート後

a_point[ hori ][ vertical ].hori_angle = 
[-180,-180,-180,-180,-180,-180,-180],
[-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ],
[0   ,0   ,0   ,0   ,0   ,0   ,0   ],
[180 ,180 ,180 ,180 ,180 ,180 ,180 ];

↓↓↓こんな感じなのかな?と予想↓↓↓
a_point[ hori ][ vertical ].vertical_angle = 
[(-10 ,20  ),10  ,0   ,(15  ,25  ),30  ],
[-10  ,10   ,0   ,(25 ,15  ),30   ,20  ],
[15   ,(30  ,25 ),(-10,20  ),10   ,0   ],
[-10  ,(25  ,20 ),(10 ,0   ),(30  ,15 )];

()内は順不同.あくまで予想です.

2.垂直角ソート後

/*垂直角ソートプログラム(Sort関数内に存在)*/

double temp1, temp2, temp3, temp4, temp5;

for(int i = 0; i < hori; i++){
   for(int j = 0; j < vertical; j++){
      for(int k = j+1; k < vertival; k++){
         temp1 = a_point[j][i].x;
         temp2 = a_point[j][i].y;
         temp3 = a_point[j][i].z;
         temp4 = a_point[j][i].hori_angle;
         temp5 = a_point[j][i].vertical_angle;

         a_point[j][i].x = a_point[k][i].x;
         a_point[j][i].y = a_point[k][I].y;
         a_point[j][i].z = a_point[k][I].z;
         a_point[j][i].hori_angle = a_point[k][i].hori_angle;
         a_point[j][i].vertical_angle = a_point[k][i].vertical_angle;

         a_point[k][i].x = temp1;
         a_point[k][i].y = temp2;
         a_point[k][i].z = temp3;
         a_point[k][i].hori_angle = temp4;
         a_point[k][i].vertical_angle = temp5;
      }
  }
}


<結果>
a_point[ hori ][ vertical ].hori_angle = 
[-180,-180,-180,-180,-180,-180,-180],
[-30 ,-30 ,-30 ,-30 ,-30 ,-30 ,-30 ],
[0   ,0   ,0   ,0   ,0   ,0   ,0   ],
[180 ,180 ,180 ,180 ,180 ,180 ,180 ];

a_point[hori][vertical].vertical_angle =
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30],
[-10,0,10,15,20,25,30];

現状

垂直角のソートのみ取り入れているので,以下のような結果が得られています.

a_point[ hori ][ vertical ].hori_angle = 
[-180,0,-30,-180,0,-30,-180],
[-30,0,180,-180,-180,0,-30,0],
[-180,0,-30,(0,180,-180),0],
[180,180,-30,(180,180),-180,-30]

a_point[hori][vertical].vertical_angle =
[-10,-10,0,10,10,15,30],
[-10,0,10,15,20,25,30],
[0,15,20,25,25,25,30],
[-10,0,10,15,20,20,30];

補足情報

a_point[][]はpoint classのことを表しています.
垂直角のソートは出来ているのですが,水平角のソート方法がわかりません.

更に詳しく編集し直しました.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • episteme

    2020/07/20 13:26

    つまり 何を/どんな 順で並べるんですか? 比較/交換規則を明らかにしてください。

    キャンセル

回答 1

0

上記<結果>が得られればいいのなら:

#include <iostream>
#include <algorithm>

int main() {
  int data[5][7] = {
    { 0, 0, 0, 1, 2, 0, 0 },
    { 1, 3, 2, 1, 0, 4, 3 },
    { 0, 1, 1, 4, 1, 1, 4 },
    { 2, 2, 4, 3, 2, 3, 2 },
    { 2, 3, 4, 4, 3, 3, 4 },
  };
  std::sort((int*)data, (int*)data+5*7);

  // できたかな?
  for ( int row = 0; row < 5; ++row ) {
    for ( int col = 0; col < 7; ++col ) {
      std::cout << data[row][col] << ' ';
    }
    std::cout << std::endl;
  }
}

[追記] 第二版

#include <iostream>
#include <algorithm>

class point {
public:
    int angle;
    point(int a) : angle(a) {};
};

int main() {
  point data[5][7] = {
    { 0, 0, 0, 1, 2, 0, 0 },
    { 1, 3, 2, 1, 0, 4, 3 },
    { 0, 1, 1, 4, 1, 1, 4 },
    { 2, 2, 4, 3, 2, 3, 2 },
    { 2, 3, 4, 4, 3, 3, 4 },
  };
  std::sort((point*)data, (point*)data+5*7,
             [](const point& a, const point& b) { return a.angle < b.angle; });

  // できたかな?
  for ( int row = 0; row < 5; ++row ) {
    for ( int col = 0; col < 7; ++col ) {
      std::cout << data[row][col].angle << ' ';
    }
    std::cout << std::endl;
  }
}


[追記] 第三版

#include <iostream>
#include <algorithm>

class point {
public:
    double hori_angle;     //xy平面上でのx軸と点の角度(以下、水平角)
    double vertical_angle; //xy平面と点のなす角度(以下、垂直角)
};

int main() {
  point data[5][7] = { ... };
  std::sort((point*)data, (point*)data+5*7,
             [](const point& a, const point& b) { 
                return a.hori_angle < b.hori_angle ||
                       (!(b.hori_angle < a.hori_angle ) && a.vertical_angle < b.vertical_angle);
                });

  // できたかな?
  for ( int row = 0; row < 5; ++row ) {
    for ( int col = 0; col < 7; ++col ) {
      std::cout << data[row][col].hori_ange << ',' << data[row][col].vertical_angle << ' ';
    }
    std::cout << std::endl;
  }
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/07/21 17:01

    ありがとうございます。
    もう少しでできそうな感じはしているのですが、data[][]の中にはどの数値を格納すれば良いのでしょうか?
    私の該当のソースコードに記載の通り、水平方向と垂直方向では同じクラス内ではありますが別の配列(表現が正しくないかも)にデータが格納されているため、何をdata[][]に設定すれば良いのかわかりませんでした。

    キャンセル

  • 2020/07/21 17:04 編集

    いやそれは僕が決めることじゃありませんよ。ソートしたい要素群を突っ込んでください。
    僕のコードは、data[][]を一次元(のリニアな)配列とみなしてソートしてるだけです。

    キャンセル

  • 2020/07/21 18:36

    ところで質問文の「垂直角ソート後」に大量の代入文が見えますが、そもそもstd::swap使いましょう。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.91%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る