🔲
nannou の範囲を扱う Rect の使い方
早見表
種類 | 意味 | Methods | 同類・補足 |
---|---|---|---|
生成 | x, y, w, h から | from_x_y_w_h | from_xy_wh |
生成 | w, h から | from_w_h | from_wh |
生成 | 対角から | from_corner_points | from_corners |
生成 | f64 で | from_xy_wh_f64 | from_wh_f64 from_corners_f64 |
参照 | 個別 | x() y() w() h() | |
参照 | 配列 | x_y() w_h() | |
参照 | ベクトル型 | xy() wh() | xy_wh |
参照 | まとめて | l_r_b_t() | l_t_w_h l_b_w_h |
参照 | 十字の先端 | mid_left() | mid_top mid_right mid_bottom |
参照 | 辺 | left() | right bottom top |
角 | 個別 | top_left() | top_right bottom_left bottom_right |
角 | まとめて | corners() | corners_iter |
角 | 指定の角座標 | corner_at_index(i) | |
角 | 座標に近い角の名前 | closest_corner(xy) | stretch_to_point の影響を受ける角が分かる |
領域 | 上下左右 | subdivision_ranges | subdivisions_iter |
領域 | 対角切断時の三角形 | triangles() | triangles_iter |
対領域 | 相手との AND | a.overlap(b) | |
対領域 | 相手との OR | a.max(b) | |
移動 | 相手の軸の ? に | a.align_x_of(?, b) | align_y_of align_middle_of |
移動 | 相手の内側の辺に | a.mid_top_of(b) | mid_bottom_of mid_left_of mid_right_of |
移動 | 相手の中心に | a.middle_of(b) | |
移動 | 相手の辺の外に | left_of(b) | right_of below above |
移動 | 相手の辺の内に | align_left_of(b) | align_right_of align_bottom_of align_top_of |
移動 | 相手の角の内に | top_left_of(b) | top_right_of bottom_left_of bottom_right_of |
変形 | 軸を動かす | shift(vec2) | shift_x shift_y |
変形 | 指定座標を覆う | stretch_to(pt2) | stretch_to_point(xy) |
変形 | 縮小 | pad | pad_left pad_right pad_bottom pad_top padding |
向き | 反転 | invert_x() | invert_y |
向き | 正にする | absolute() | |
その他 | 座標が含まれるか? | contains(pt2) | contains_point(xy) |
その他 | 相対的な領域を返す | relative_to(xy) | relative_to_x relative_to_y |
コンストラクタ
x, y, w, h から作る
let a = Rect::from_x_y_w_h(0.0, 0.0, 100.0, 100.0);
a.x; // => Range { start: -50.0, end: 50.0 }
a.y; // => Range { start: -50.0, end: 50.0 }
よくあるのが x, y, w, h のメンバーを持った構造体だったり (x, y) と (w, h) がベクトルになっていたりするタイプだが、Nannou の Rect は Range::from_pos_and_len(x, w)
と Range::from_pos_and_len(y, h)
で生成した Range のインスタンスを x, y に持っているという驚きのそして非常に考えられた構造になっている。
w, h から作る
let a = Rect::from_w_h(100.0, 100.0);
a.x; // => Range { start: -50.0, end: 50.0 }
a.y; // => Range { start: -50.0, end: 50.0 }
角を指定して領域を作る
Rect::from_corner_points([-10, 10], [-10, 10]); // => Rect { x: Range { start: -10, end: -10 }, y: Range { start: 10, end: 10 } }
f64 で作る
Rect::from_xy_wh_f64(dvec2(0.0, 0.0), dvec2(10.0, 10.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
Rect::from_wh_f64(dvec2(10.0, 10.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
Rect::from_corners_f64(dvec2(-5.0, 5.0), dvec2(5.0, -5.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
基本的な値の取得
let a = Rect::from_x_y_w_h(10.0, 20.0, 100.0, 100.0);
a.x(); // => 10.0
a.y(); // => 20.0
a.w(); // => 100.0
a.h(); // => 100.0
a.x_y(); // => (10.0, 20.0)
a.w_h(); // => (100.0, 100.0)
整列
a を b の座標の align に揃える
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
let b = Rect::from_x_y_w_h(0.0, 0.0, 100.0, 100.0);
a.align_x_of(Align::Start, b); // => Rect { x: Range { start: -50.0, end: -40.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_x_of(Align::Middle, b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_x_of(Align::End, b); // => Rect { x: Range { start: 40.0, end: 50.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_y_of(Align::Start, b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -50.0, end: -40.0 } }
a.align_y_of(Align::Middle, b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_y_of(Align::End, b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: 40.0, end: 50.0 } }
a.align_x_of(Align::Middle, b)
と a.align_y_of(Align::Middle, b)
のショートカット:
a.align_middle_x_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_middle_y_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
a を b の内側の上下左右の辺にくっつける
a.mid_top_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: 40.0, end: 50.0 } }
a.mid_bottom_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -50.0, end: -40.0 } }
a.mid_left_of(b); // => Rect { x: Range { start: -50.0, end: -40.0 }, y: Range { start: -5.0, end: 5.0 } }
a.mid_right_of(b); // => Rect { x: Range { start: 40.0, end: 50.0 }, y: Range { start: -5.0, end: 5.0 } }
a を b の中心に配置する
a.middle_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
中央で区切って上下左右の範囲を返す
let a = Rect::from_x_y_w_h(200.0, 300.0, 10.0, 10.0);
let b = a.subdivision_ranges();
b.y_a; // => Range { start: 295.0, end: 300.0 }
b.y_b; // => Range { start: 300.0, end: 305.0 }
b.x_a; // => Range { start: 195.0, end: 200.0 }
b.x_b; // => Range { start: 200.0, end: 205.0 }
イテレータを返すメソッドもある
a.subdivisions_iter().for_each(|e| println!("{:?}", e));
内部の方向を正にする
let a = Rect { x: Range::new(1.0, -1.0), y: Range::new(1.0, -1.0) };
a; // => Rect { x: Range { start: 1.0, end: -1.0 }, y: Range { start: 1.0, end: -1.0 } }
a.absolute(); // => Rect { x: Range { start: -1.0, end: 1.0 }, y: Range { start: -1.0, end: 1.0 } }
同じ領域でも右下から左上の向きになっている場合がある。それを左上から右下方向に直す。
AND 領域
let a = Rect::from_x_y_w_h(100.0, 100.0, 100.0, 100.0);
let b = Rect::from_x_y_w_h(150.0, 150.0, 100.0, 100.0);
a.overlap(b); // => Some(Rect { x: Range { start: 100.0, end: 150.0 }, y: Range { start: 100.0, end: 150.0 } })
OR 領域
let a = Rect::from_x_y_w_h(100.0, 100.0, 100.0, 100.0);
let b = Rect::from_x_y_w_h(150.0, 150.0, 100.0, 100.0);
a.max(b); // => Rect { x: Range { start: 50.0, end: 200.0 }, y: Range { start: 50.0, end: 200.0 } }
辺の座標
let a = Rect::from_x_y_w_h(100.0, 100.0, 100.0, 100.0);
a.left(); // => 50.0
a.right(); // => 150.0
a.bottom(); // => 50.0
a.top(); // => 150.0
まとめて
a.l_r_b_t(); // => (50.0, 150.0, 50.0, 150.0)
x y をそれぞれ移動
let a = Rect::from_x_y_w_h(0.0, 0.0, 100.0, 100.0);
a; // => Rect { x: Range { start: -50.0, end: 50.0 }, y: Range { start: -50.0, end: 50.0 } }
a.shift_x(25.0); // => Rect { x: Range { start: -25.0, end: 75.0 }, y: Range { start: -50.0, end: 50.0 } }
a.shift_y(25.0); // => Rect { x: Range { start: -50.0, end: 50.0 }, y: Range { start: -25.0, end: 75.0 } }
相手の辺の外側に移動する
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
let b = Rect::from_x_y_w_h(0.0, 0.0, 100.0, 100.0);
a.left_of(b); // => Rect { x: Range { start: -60.0, end: -50.0 }, y: Range { start: -5.0, end: 5.0 } }
a.right_of(b); // => Rect { x: Range { start: 50.0, end: 60.0 }, y: Range { start: -5.0, end: 5.0 } }
a.below(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -60.0, end: -50.0 } }
a.above(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: 50.0, end: 60.0 } }
below: 下above: 上
相手の辺の内側に移動する
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
let b = Rect::from_x_y_w_h(0.0, 0.0, 100.0, 100.0);
a.align_left_of(b); // => Rect { x: Range { start: -50.0, end: -40.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_right_of(b); // => Rect { x: Range { start: 40.0, end: 50.0 }, y: Range { start: -5.0, end: 5.0 } }
a.align_bottom_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -50.0, end: -40.0 } }
a.align_top_of(b); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: 40.0, end: 50.0 } }
相手の角の内側に移動する
a.top_left_of(b); // => Rect { x: Range { start: -50.0, end: -40.0 }, y: Range { start: 40.0, end: 50.0 } }
a.top_right_of(b); // => Rect { x: Range { start: 40.0, end: 50.0 }, y: Range { start: 40.0, end: 50.0 } }
a.bottom_left_of(b); // => Rect { x: Range { start: -50.0, end: -40.0 }, y: Range { start: -50.0, end: -40.0 } }
a.bottom_right_of(b); // => Rect { x: Range { start: 40.0, end: 50.0 }, y: Range { start: -50.0, end: -40.0 } }
指定の x, y が範囲に含まれるか?
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.contains_point([0.0, 0.0]); // => true
a.contains_point([6.0, 6.0]); // => false
指定の座標を含むように近い方の辺を広げる
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.stretch_to_point([6.0, 6.0]); // => Rect { x: Range { start: -5.0, end: 6.0 }, y: Range { start: -5.0, end: 6.0 } }
指定の座標にいちばん近い角の名前を返す
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.closest_corner([1.0, 1.0]); // => TopRight
a.closest_corner([-1.0, -1.0]); // => BottomLeft
a.closest_corner([-1.0, 1.0]); // => TopLeft
a.closest_corner([1.0, -1.0]); // => BottomRight
角の座標を返す
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.corners(); // => Quad([[-5.0, 5.0], [5.0, 5.0], [5.0, -5.0], [-5.0, -5.0]])
イテレータを返すメソッドもある
a.corners_iter().for_each(|e| println!("{:?}", e));
四角形を斜めに切ってできる三角形を得る
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.triangles(); // => (Tri([[-5.0, 5.0], [5.0, 5.0], [5.0, -5.0]]), Tri([[-5.0, 5.0], [5.0, -5.0], [-5.0, -5.0]]))
左上から右下に切ったときの右上と左下の三角形が2つ返ってくる
イテレータを返すメソッドもある
a.triangles_iter().for_each(|e| println!("{:?}", e));
角の座標をインデックスで得る
let a = Rect::from_x_y_w_h(0.0, 0.0, 10.0, 10.0);
a.corner_at_index(0); // => Some([-5.0, 5.0])
a.corner_at_index(1); // => Some([5.0, 5.0])
a.corner_at_index(2); // => Some([5.0, -5.0])
a.corner_at_index(3); // => Some([-5.0, -5.0])
a.corner_at_index(4); // => None
ベクトルや Point2 から作る
Rect::from_xy_wh(pt2(0.0, 0.0), vec2(10.0, 10.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
Rect::from_wh(vec2(10.0, 10.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
Rect::from_corners(pt2(-5.0, 5.0), pt2(5.0, -5.0)); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
基本的な情報の参照
let a = Rect::from_wh(pt2(100.0, 100.0));
a.xy(); // => Vec2(0.0, 0.0)
a.wh(); // => Vec2(100.0, 100.0)
a.xy_wh(); // => (Vec2(0.0, 0.0), Vec2(100.0, 100.0))
a.top_left(); // => Vec2(-50.0, 50.0)
a.top_right(); // => Vec2(50.0, 50.0)
a.bottom_left(); // => Vec2(-50.0, -50.0)
a.bottom_right(); // => Vec2(50.0, -50.0)
a.mid_left(); // => Vec2(-50.0, 0.0)
a.mid_top(); // => Vec2(0.0, 50.0)
a.mid_right(); // => Vec2(50.0, 0.0)
a.mid_bottom(); // => Vec2(0.0, -50.0)
x, y をまとめて移動
let a = Rect::from_wh(vec2(100.0, 100.0));
a.shift(vec2(10.0, 10.0)); // => Rect { x: Range { start: -40.0, end: 60.0 }, y: Range { start: -40.0, end: 60.0 } }
指定の座標が含まれるか?
let a = Rect::from_wh(vec2(100.0, 100.0));
a.contains(pt2(0.0, 0.0)); // => true
a.contains(vec2(0.0, 0.0)); // => true
pt2 は vec2 と書いてもいいらしい
指定の座標が含まれるまで近い方を伸ばす
let a = Rect::from_wh(vec2(2.0, 2.0));
a.stretch_to(pt2(5.0, 5.0)); // => Rect { x: Range { start: -1.0, end: 5.0 }, y: Range { start: -1.0, end: 5.0 } }
左上wh や 左下wh をまとめて得る
let a = Rect::from_wh(vec2(100.0, 100.0));
a.l_t_w_h(); // => (-50.0, 50.0, 100.0, 100.0)
a.l_b_w_h(); // => (-50.0, -50.0, 100.0, 100.0)
内側に辺をずらす
let a = Rect::from_wh(vec2(100.0, 100.0));
a.pad_left(10.0); // => Rect { x: Range { start: -40.0, end: 50.0 }, y: Range { start: -50.0, end: 50.0 } }
a.pad_right(10.0); // => Rect { x: Range { start: -50.0, end: 40.0 }, y: Range { start: -50.0, end: 50.0 } }
a.pad_bottom(10.0); // => Rect { x: Range { start: -50.0, end: 50.0 }, y: Range { start: -40.0, end: 50.0 } }
a.pad_top(10.0); // => Rect { x: Range { start: -50.0, end: 50.0 }, y: Range { start: -50.0, end: 40.0 } }
a.pad(10.0); // => Rect { x: Range { start: -40.0, end: 40.0 }, y: Range { start: -40.0, end: 40.0 } }
let p = Padding { x: Range::new(10.0, 10.0), y: Range::new(10.0, 10.0) };
a.padding(p); // => Rect { x: Range { start: -40.0, end: 40.0 }, y: Range { start: -40.0, end: 40.0 } }
相対的な範囲を返す
let a = Rect::from_wh(vec2(10.0, 10.0));
a; // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -5.0, end: 5.0 } }
a.relative_to_x(10.0); // => Rect { x: Range { start: -15.0, end: -5.0 }, y: Range { start: -5.0, end: 5.0 } }
a.relative_to_y(10.0); // => Rect { x: Range { start: -5.0, end: 5.0 }, y: Range { start: -15.0, end: -5.0 } }
a.relative_to([10.0, 10.0]); // => Rect { x: Range { start: -15.0, end: -5.0 }, y: Range { start: -15.0, end: -5.0 } }
反転
let a = Rect::from_wh(vec2(2.0, 2.0));
a; // => Rect { x: Range { start: -1.0, end: 1.0 }, y: Range { start: -1.0, end: 1.0 } }
a.invert_x(); // => Rect { x: Range { start: 1.0, end: -1.0 }, y: Range { start: -1.0, end: 1.0 } }
a.invert_y(); // => Rect { x: Range { start: -1.0, end: 1.0 }, y: Range { start: 1.0, end: -1.0 } }
Discussion