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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

2回答

2268閲覧

ポアソンディスクサンプリングのプログラムについてまたエラーinvalid declarator before 'poi'

langhtorn

総合スコア104

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2020/08/01 01:53

編集2020/08/01 02:28

###実現したいこと
ポアソンディスクサンプリングのプログラムを作りたい
std::vector<Point> poisson_disk_sampling(int n,double r,std::mt19937& random)関数の中で
0. 単位正方形の中に、ランダムに1点pを発生させる
0. pと既に得られた各生成点との距離の最小値を計算する
0. 最小距離が2r未満なら、ステップ1に戻ってやり直す。最小距離が2r以上なら、pを新たに生成点として加える

という過程を踏んで作りたです。

###問題点
下記のようなエラーがでてきました。
invalid declarator before 'poi'を検索してみたのですが出てこずこのエラーの意味がわかりません。
また、pと既に得られた各生成点との距離の最小値を計算するの部分があっているかどうか自信がありません。
エラー

kadai36.cpp: In function 'std::vector<Point> poisson_disk_sampling(int, double, std::mt19937&)': kadai36.cpp:45:24: error: invalid declarator before 'poi' 45 | std::vector<Point> poi; // ^~~ kadai36.cpp:56:35: error: array must be initialized with a brace-enclosed initializer 56 | double dis[j]=distance(p[i],p[j]); | ~~~~~~~~^~~~~~~~~~~ kadai36.cpp:65:9: error: 'poi' was not declared in this scope; did you mean 'pow'? 65 | poi.push_back(p); | ^~~ | pow kadai36.cpp:68:12: error: 'poi' was not declared in this scope; did you mean 'pow'? 68 | return poi; | ^~~ | pow

###コード

C++

1#include<iostream> 2#include<vector> 3#include<random> 4#include<cmath> 5 6struct Point 7{ 8 double x; //x座標 9 double y; //y座標 10 11 void output() 12 { 13 std::cout<<"("<<x<<","<<y<<")\n"; 14 } 15}; 16 17void output_points(std::vector<Point>& points) 18{ 19 int n=points.size(); 20 int i; 21 for(i=0;i<n;i++){ 22 points[i].output(); 23 } 24} 25 26//2点間の距離を求める 27double distance(Point a,Point b) 28{ 29 double d=std::sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 30 return d; 31} 32 33 34//ポアソンディスサンプリングにより、単位正方形の中にn個の点を生成する関数 35std::vector<Point> poisson_disk_sampling(int n,double r,std::mt19937& random) 36{ 37 int i,j; 38 double dis[n],min; 39 Point p[n]; 40 int 41 42 std::vector<Point> poi; //生成点の集合 43 44 for(i=0;i<n;i++){ 45 do{ 46 //単正方形の中に、ランダムに1点pを発生させる 47 p[i].x=i+(n-1-i)*(random()/(random.max()+1.0)); 48 p[i].y=i+(n-1-i)*(random()/(random.max()+1.0)); 49 50 //pと既に得られた各生成点との距離の最小値を計算する 51 double min=dis[0]; 52 for(j=1;j<n;j++){ 53 double dis[j]=distance(p[i],p[j]); 54 if(min>dis[j]){ 55 min=dis[j]; 56 } 57 } 58 }while(min<2*r); 59 60 //最小距離が2r未満なら、ステップ1に戻ってやり直す。 61 //最小距離が2r以上なら、pを新たに生成点として加える 62 poi.push_back(p); 63 } 64 65 return poi; 66 67} 68 69int main(int argc,char* argv[]) 70{ 71 int i; 72 unsigned int seed_val; 73 if(argc>=2){ 74 seed_val=std::atoi(argv[1]); 75 }else{ 76 std::random_device seeder; 77 seed_val=seeder(); 78 } 79 80 std::mt19937 random; 81 random.seed(seed_val); 82 int n; 83 std::cout<<"何個ですか : "; 84 std::cin>>n; 85 86 87 //円の半径を求める 88 double r=sqrt(1/2*sqrt(3)*n)*0.75; 89 90 std::vector<Point> poisson=poisson_disk_sampling(n,r,random); 91 92 std::cout<<"結果の座標は"; 93 94 output_points(poisson); 95 96 return 0; 97}

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

invalid declarator before 'poi'を検索してみたのですが出てこずこのエラーの意味がわかりません。

検索する前に、エラーメッセージを読んでください。
error: invalid declarator before 'poi'
英語だから読まないのですか?
「'poi' の前の不正な宣言子」
declarator の意味がよく分からなくても宣言(declaration)に関係するエラーだと
分かるでしょう。
45行目だといっているのでそこを見ましょう。
std::vector<Point> poi;
正しい宣言です。
ところがその前の前の行から見ましょう。

C++

1 int 2 3 std::vector<Point> poi; //生成点の集合

宣言は int から始まっています。
int は型名、std::vector<Point> も型名、poi は変数名。
宣言は「型名 変数名;」ですから、間違いですね。

int を削除しましょう。

array must be initialized with a brace-enclosed initializer
「配列は、ブレイスで囲まれた初期化子で初期化されなければならない」
ブレイスとは、{ と } です。

double dis[j]=distance(p[i],p[j]);
double dis[j] = { distance(p[i],p[j]) }; にしなさい
と言っているように取れますが、ソースをよく見てください。
15行前に、double dis[n],min; という宣言があります。
dis は既に宣言されていて、それを使えばいいのに、新たに double
配列 dis を宣言しようとしてエラーになっていることが分かります。

修正方法は、double を削除して、dis[j] = distance(p[i], p[j]); にする。

また、pと既に得られた各生成点との距離の最小値を計算するの部分があっているかどうか自信がありません。

合っていません。

投稿2020/08/01 03:46

編集2020/08/01 04:12
kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

langhtorn

2020/08/03 12:57

エラーをちゃんと英語として読みます。ありがとうございます。
guest

0

double dis[n],min;
Point p[n];

こんなこと(引数値nを用いた配列の定義)はできない.

投稿2020/08/01 03:00

fana

総合スコア11658

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kazuma-s

2020/08/01 03:48

コンパイラが g++ ですから、GNU拡張により C99 と同様、可変長配列が使用できます。
Daregada

2020/08/01 03:53

gcc拡張文法とかGNU拡張ってやつで、この部分は「今回の問題」ではありません。
fana

2020/08/01 04:07

それでは間違いであるとわかるように低評価を依頼致す所存.
Daregada

2020/08/01 04:12

「誤チェストにごわす」
fana

2020/08/01 04:17

感謝.
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問