-
Notifications
You must be signed in to change notification settings - Fork 2
Added the basic Rotors Template #2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| const std = @import("std"); | ||
| const vec = @import("vector.zig"); | ||
| const Mat4x4 = @import("matrix.zig").@"4x4"; | ||
| const Quaternion = @import("quaternion.zig").Hamiltonian; | ||
|
|
||
| pub fn Rotor(T: type) type { | ||
| return struct { | ||
| scalar: T, | ||
| xy: T, | ||
| yz: T, | ||
| zx: T, | ||
|
|
||
| pub const identity: @This() = .{ .scalar = 0, .xy = 0, .yz = 0, .zx = 0 }; | ||
|
|
||
| pub fn new(scalar: T, xy: T, yz: T, zx: T) @This() { | ||
| return .{ .scalar = scalar, .xy = xy, .yz = yz, .zx = zx }; | ||
| } | ||
|
|
||
| pub fn combine(lhs: @This(), rhs: @This()) @This() { | ||
| var result: @This() = undefined; | ||
| result.scalar = lhs.scalar * rhs.scalar - lhs.xy * rhs.xy - lhs.yz * rhs.yz - lhs.zx * rhs.zx; | ||
| result.xy = lhs.scalar * rhs.xy + lhs.xy * rhs.scalar - lhs.yz * rhs.zx + lhs.zx * rhs.yz; | ||
| result.yz = lhs.scalar * rhs.yz + lhs.xy * rhs.zx + lhs.yz * rhs.scalar - lhs.zx * rhs.xy; | ||
| result.zx = lhs.scalar * rhs.zx - lhs.xy * rhs.yz + lhs.yz * rhs.xy + lhs.zx * rhs.scalar; | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| pub fn reverse(r: @This()) @This() { | ||
| var result: @This() = undefined; | ||
| result.scalar = r.scalar; | ||
| result.xy = -r.xy; | ||
| result.yz = -r.yz; | ||
| result.zx = -r.zx; | ||
| return result; | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can do result = .{ } and use aggregate struct initialization. |
||
|
|
||
| pub fn transform(r: @This(), v: @Vector(3, T)) @Vector(3, T) { | ||
| const S_x: f32 = r.scalar * v[0] + r.xy * v[1] - r.zx * v[2]; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. always have variables and constants as snake_case with no upper case letters |
||
| const S_y: f32 = r.scalar * v[1] - r.xy * v[0] + r.yz * v[2]; | ||
| const S_z: f32 = r.scalar * v[2] - r.yz * v[1] + r.zx * v[1]; | ||
| const S_xyz = r.xy * v[2] + r.zy * v[0] + r.zx * v[1]; | ||
|
|
||
| var result: @Vector(3, T) = undefined; | ||
| result[0] = S_x * r.scalar + S_y * r.xy + S_xyz * r.yz - S_z * r.zx; | ||
| result[1] = S_y * r.scalar - S_x * r.xy + S_z * r.yz + S_xyz * r.zx; | ||
| result[2] = S_z * r.scalar + S_xyz * r.xy - S_y * r.yz + S_x * r.zx; | ||
| return result; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same here, you can just do return .{
result[0] = S_x * r.scalar + S_y * r.xy + S_xyz * r.yz - S_z * r.zx;
result[1] = S_y * r.scalar - S_x * r.xy + S_z * r.yz + S_xyz * r.zx;
result[2] = S_z * r.scalar + S_xyz * r.xy - S_y * r.yz + S_x * r.zx;
} |
||
| } | ||
|
|
||
| pub fn rotate(r: @This()) Mat4x4(T) { | ||
| const new_x: @Vector(3, T) = transform(r, @Vector(3, f32){ 1.0, 0.0, 0.0 }); | ||
| const new_y: @Vector(3, T) = transform(r, @Vector(3, f32){ 0.0, 1.0, 0.0 }); | ||
| const new_z: @Vector(3, T) = transform(r, @Vector(3, f32){ 0.0, 0.0, 1.0 }); | ||
|
|
||
| const result: Mat4x4(T) = .new(.{ new_x[0], new_x[1], new_x[2], 0.0, new_y[0], new_y[1], new_y[2], 0.0, new_z[0], new_z[1], new_z[2], 0.0, 0.0, 0.0, 0.0, 0.0 }); | ||
| return result; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can instantly just do return .new( [...] ) |
||
| } | ||
|
|
||
| pub fn quaternion_to_rotor3(q: Quaternion(T)) @This() { | ||
| var result: @This() = undefined; | ||
| result.scalar = q.w; | ||
| result.xy = -q.z; | ||
| result.yz = -q.x; | ||
| result.zx = -q.y; | ||
| return result; | ||
| } | ||
|
|
||
| fn lerp(a: f32, b: f32, t: f32) f32 { | ||
| return a + t * (b - a); | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe there is |
||
|
|
||
| pub fn nlerp(lhs: @This(), rhs: @This(), t: f32) @This() { | ||
| const dot: f32 = lhs.scalar * rhs.scalar + lhs.xy * rhs.xy + lhs.yz * rhs.yz + lhs.zx * rhs.zx; | ||
| if (dot < 0.0) { | ||
| rhs.scalar = -rhs.scalar; | ||
| rhs.xy = -rhs.xy; | ||
| rhs.yz = -rhs.yz; | ||
| rhs.zx = -rhs.zx; | ||
| } | ||
|
|
||
| var r: @This() = undefined; | ||
| r.scalar = lerp(lhs.scalar, rhs.scalar, t); | ||
| r.xy = lerp(lhs.xy, rhs.xy, t); | ||
| r.yz = lerp(lhs.yz, rhs.yz, t); | ||
| r.zx = lerp(lhs.zx, rhs.zx, t); | ||
|
|
||
| const magnitude: f32 = std.math.sqrt(r.scalar * r.scalar + r.xy * r.xy + r.yz * r.yz + r.zx * r.zx); | ||
| r.scalar = r.scalar / magnitude; | ||
| r.xy = r.xy / magnitude; | ||
| r.yz = r.yz / magnitude; | ||
| r.zx = r.zx / magnitude; | ||
| return r; | ||
| } | ||
|
|
||
| pub fn slerp(from: @This(), to: @This(), t: f32) @This() { | ||
| var dot: f32 = from.scalar * to.scalar + from.xy * to.xy + from.yz * to.yz + from.zx * to.zx; | ||
| if (dot < 0.0) { | ||
| to.scalar = -to.scalar; | ||
| to.xy = -to.xy; | ||
| to.yz = -to.yz; | ||
| to.zx = -to.zx; | ||
| dot = -dot; | ||
| } | ||
|
|
||
| if (dot > 0.99995) { | ||
| return nlerp(from, to, t); | ||
| } | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would do if (dot > 0.99995) return nlerp(from, to, t); |
||
|
|
||
| const cos_theta = dot; | ||
| const theta: f32 = std.math.acos(cos_theta); | ||
| const from_factor: f32 = std.math.sin((1.0 - t) * theta / std.math.sin(theta)); | ||
| const to_factor: f32 = std.math.sin((t * theta) / std.math.sin(theta)); | ||
|
|
||
| var result: @This() = undefined; | ||
| result.scalar = from_factor * from.scalar + to_factor * to.scalar; | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here just do return .{
.scalar = from_factor * from.scalar + to_factor * to.scalar;
.xy = from_factor * from.xy + to_factor * to.xy;
.yz = from_factor * from.yz + to_factor * to.yz;
.zx = from_factor * from.zx + to_factor * to.zx;
}; |
||
| result.xy = from_factor * from.xy + to_factor * to.xy; | ||
| result.yz = from_factor * from.yz + to_factor * to.yz; | ||
| result.zx = from_factor * from.zx + to_factor * to.zx; | ||
| return result; | ||
| } | ||
|
|
||
| pub fn from_vec_to_rotor(from_dir: @Vector(3, T), to_dir: @Vector(3, T)) @This() { | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. functions are typicaly camelCase, not snake_case |
||
| // This function might be completely incorrect I may need to re review | ||
| from_dir = vec.normalize(from_dir); | ||
| to_dir = vec.normalize(to_dir); | ||
|
|
||
| const halfway: @Vector(3, T) = vec.normalize(from_dir + to_dir); | ||
|
|
||
| const wedge = @Vector(3, T){ | ||
| (halfway[0] * from_dir[1]) - (halfway[1] * from_dir[0]), | ||
| (halfway[1] * from_dir[2]) - (halfway[2] * from_dir[1]), | ||
| (halfway[2] * from_dir[0]) - (halfway[0] * from_dir[2]), | ||
| }; | ||
|
|
||
| var result: @This() = undefined; | ||
|
|
||
| result.scalar = vec.dot(from_dir, halfway); | ||
| result.xy = wedge.x; | ||
| result.yz = wedge.y; | ||
| result.zx = wedge.z; | ||
| return result; | ||
| } | ||
| }; | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.