前回、
で、クロソイド曲線を描きました。前回のは、ellipseで小さい円をいっぱい描いて線のように描いていました。
今回は、polylineで同じものを描いていきます。さらに、カラー化もしていきます。
polylineって何?って思う方は、rust nannouのpolylineを使うを見てください。描き方を解説してます。
まぁ、pathのデータを送ってそれを線でつないでくれるっていう感じです。
ではやっていきましょう。
polylineでクロソイド曲線を描く
クロソイド曲線のおさらいですが
$$x(l)=\int_0^l cos(\frac{\theta^2}{2}) d\theta$$
$$y(l)=\int_0^l sin(\frac{\theta^2}{2}) d\theta$$
これをグラフに書いていく感じです。
詳しい値の計算方法は、前回のrust nannouでクロソイド曲線を描くで解説していますので、そちらをお願いします。
今回はpolylineでクロソイド曲線を描く方法を解説ます。
polylineで描画するときは、pathを作ってそれを描画していきます。
pathを作っていく
polylineで描画するときは、pathを使います。pathは、一個一個の座標をベクタ型にして記録しておきます。
相手に渡すときはイテレーターね。
なので、まずは、Struct Modelの中にVector2のベクタを作ります。
my_point: Vec<Vector2>,
次にmodel関数の中で、my_pointを初期化します。
let mut my_point = Vec::new();
model.my_point.push(pt2(0.0,0.0));
Model{
my_point,
}
こんな感じね。
次にupdate関数に行って、クロソイド曲線の計算結果を毎回、座標pt2(x,y)の形をmy_pointに追加するようにします。
fn update(_app: &App, model: &mut Model, _update: Update) {
//クロソイド曲線の積分の計算
let delta_theta = 0.01;
model.theta += delta_theta;
model.x += (model.theta * model.theta * 0.5).cos();
model.y += (model.theta * model.theta * 0.5).sin();
//polylineのためのベクタに追加
model.my_point.push(pt2(model.x,model.y));
}
これで、pathのデータづくりは完了です。
polylineの描画をしていく
データができたので、あとは描画を描いていきます。
これは簡単
draw.polyline()
.weight(5.0)//線の太さ
.points(model.my_point.clone())//ここでパスを渡す
.color(RED);//色の指定
こんな感じね。
これで、polylineによるクロソイド曲線の完成
このサイズでパッと見た目は変わりませんが、ellipseの場合は無数に点を打って線っぽく描いているのに対して、polylineは点を線でつないで描いています。
polylineをカラー化する
ここまでで、まずはpolylineで描くことができました。ここからは、さらにこれをカラー化してきます。
カラー化?すでに赤いじゃん?って思うかもしれませんが、これは、全体に赤っていう指定をしただけです。
カラー化するってのはこういうことです。
右上がカラー化したpolylineのクロソイド曲線
まるでカメレオンのようですね。
これをどうやるかですが、polylineに渡すpath情報でpoints_coloredっていう色情報をセットで渡す方法があります。
draw.polyline()
.weight(5.0)//線の太さ
.points_colored(色情報付きのpath情報);
データとしては(p,c)ポイントとカラーをこんな感じにしたイテレーター使えるデータ形式で渡すことになります。
ではこれを作っていきましょう。
色情報を作る
色情報をセットで渡すんですが、そのための色情報を作ります。
もちろんですけど、色情報もイテレータにするので、その場所と初期化をチャチャっとしちゃいましょう
struct Model{
...
...
my_color:Vec<Hsl>,
}
色情報を持ったベクタを作る。HslじゃなくてRgbとかHsvとか好きなものでOK
fn model(.....){
....
....
let mut my_color = Vec::new();
my_color.push(hsl(0.5, 1.0, 0.3));//適当な色で初期化
Model{
.....
.....
my_color,
}
適当な色で初期化しておく
fn update(......){
.....
.....
model.my_color.push(hsl(...,...,...,));
}
色の作り方は自由です。
これで、色情報は完成
座標と色を一つにまとめる
座標情報(my_point)と色情報(my_color)ができたので、これをcolored_pointに渡すために(p,c)っていう形のベクタにしていきます。
let cp = (0..model.my_point.len())
.map(|i|{
let points = model.my_point[i];
let colors = model.my_color[i];
(points,colors)
});
最後にこれをpolylineに渡します
draw.polyline()
.weight(5.0)//線の太さ
.points_colored(cp);
これで完成!
まとめ
polylineによる描画とさらにカラー化
データをどういう風に調理していくのかがポイントでした。
僕も結構苦労したんだけど、適当に?やったら意外とできちゃって
他にも方法があるかもしれませんが、僕は今回のようにやりました。
ではまた!
コメント