# Cookbook (copy/paste snippets)
All snippets are intended to be copy-pastable. Some require specific feature flags; each section lists the minimal required features.
## Units/spaces: “make invalid math not compile”
**Requires**: `vec2` (or `full`)
```rust
use gemath::{Meters, Pixels, Screen, Vec2, World};
let p_world: Vec2<Meters, World> = Vec2::new(10.0, 20.0);
let p_screen: Vec2<Pixels, Screen> = Vec2::new(640.0, 360.0);
// let _ = p_world + p_screen;
// ^ compile error: different Unit and Space tags
```
## 2D rotation (typed angles)
**Requires**: `vec2` (or `full`)
```rust
use gemath::{Degrees, Vec2};
let v: Vec2<(), ()> = Vec2::new(1.0, 0.0);
let v90 = v.rotate_deg(Degrees(90.0));
assert!((v90 - Vec2::new(0.0, 1.0)).length() < 1e-5);
```
## TRS compose / decompose (Mat4)
**Requires**: `mat4` + `quat` (or `full`)
```rust
use gemath::{Mat4, Quat, Radians, Vec3};
let t = Vec3::new(1.0, 2.0, 3.0);
let r: Quat<(), ()> = Quat::from_axis_angle_radians(
Vec3::new(0.0, 0.0, 1.0),
Radians(core::f32::consts::FRAC_PI_4),
);
let s = Vec3::new(2.0, 3.0, 4.0);
let m: Mat4<(), ()> = Mat4::from_trs(t, r, s);
let (t2, _r2, s2) = m.decompose();
assert!((t2 - t).length() < 1e-5);
assert!((s2 - s).length() < 1e-4);
```
## Camera look-at (left-handed)
**Requires**: `mat4` (or `full`)
```rust
use gemath::{Mat4, Vec3};
let eye = Vec3::new(0.0, 0.0, -5.0);
let target = Vec3::new(0.0, 0.0, 0.0);
let up = Vec3::new(0.0, 1.0, 0.0);
let view: Mat4<(), ()> = Mat4::look_at_lh(eye, target, up);
// The eye should map near the origin in view space.
let eye_vs = view.transform_point(eye);
assert!(eye_vs.length() < 1e-4);
```
## Raycasts with structured hit results
**Requires**: `collision` (or `full`)
```rust
use gemath::{ray2_circle_cast, Circle, Ray2, Vec2};
let circle: Circle<(), ()> = Circle::new(Vec2::new(0.0, 0.0), 1.0);
let ray: Ray2<(), ()> = Ray2::new(Vec2::new(-2.0, 0.0), Vec2::new(1.0, 0.0));
let hit = ray2_circle_cast(ray, circle).unwrap();
assert!((hit.t - 1.0).abs() < 1e-6);
assert!((hit.point - Vec2::new(-1.0, 0.0)).length() < 1e-6);
assert!((hit.normal - Vec2::new(-1.0, 0.0)).length() < 1e-6);
```
## Allocation-backed polygons (concave point-in-polygon)
**Requires**: `polygon2` + (`std` or `alloc`)
```rust
use gemath::{Polygon2, Vec2};
let poly: Polygon2<(), ()> = Polygon2::new(vec![
Vec2::new(0.0, 0.0),
Vec2::new(3.0, 0.0),
Vec2::new(3.0, 2.0),
Vec2::new(2.0, 2.0),
Vec2::new(2.0, 3.0),
Vec2::new(0.0, 3.0),
]);
assert!(poly.contains_point(Vec2::new(0.5, 2.5))); // inside
assert!(!poly.contains_point(Vec2::new(2.5, 2.5))); // in the removed notch
```