Add custom types for position (#15204)
This commit is contained in:
@ -339,19 +339,19 @@ bool L6470_Marlin::get_user_input(uint8_t &driver_count, uint8_t axis_index[3],
|
||||
// Position calcs & checks
|
||||
//
|
||||
|
||||
const float center[] = {
|
||||
LOGICAL_X_POSITION(current_position[X_AXIS]),
|
||||
LOGICAL_Y_POSITION(current_position[Y_AXIS]),
|
||||
LOGICAL_Z_POSITION(current_position[Z_AXIS]),
|
||||
current_position[E_AXIS]
|
||||
const xyze_pos_t center = {
|
||||
LOGICAL_X_POSITION(current_position.x),
|
||||
LOGICAL_Y_POSITION(current_position.y),
|
||||
LOGICAL_Z_POSITION(current_position.z),
|
||||
current_position.e
|
||||
};
|
||||
|
||||
switch (axis_mon[0][0]) {
|
||||
default: position_max = position_min = 0; break;
|
||||
|
||||
case 'X': {
|
||||
position_min = center[X_AXIS] - displacement;
|
||||
position_max = center[X_AXIS] + displacement;
|
||||
position_min = center.x - displacement;
|
||||
position_max = center.x + displacement;
|
||||
echo_min_max('X', position_min, position_max);
|
||||
if (false
|
||||
#ifdef X_MIN_POS
|
||||
@ -367,8 +367,8 @@ bool L6470_Marlin::get_user_input(uint8_t &driver_count, uint8_t axis_index[3],
|
||||
} break;
|
||||
|
||||
case 'Y': {
|
||||
position_min = center[Y_AXIS] - displacement;
|
||||
position_max = center[Y_AXIS] + displacement;
|
||||
position_min = center.y - displacement;
|
||||
position_max = center.y + displacement;
|
||||
echo_min_max('Y', position_min, position_max);
|
||||
if (false
|
||||
#ifdef Y_MIN_POS
|
||||
@ -384,8 +384,8 @@ bool L6470_Marlin::get_user_input(uint8_t &driver_count, uint8_t axis_index[3],
|
||||
} break;
|
||||
|
||||
case 'Z': {
|
||||
position_min = center[Z_AXIS] - displacement;
|
||||
position_max = center[Z_AXIS] + displacement;
|
||||
position_min = center.z - displacement;
|
||||
position_max = center.z + displacement;
|
||||
echo_min_max('Z', position_min, position_max);
|
||||
if (false
|
||||
#ifdef Z_MIN_POS
|
||||
@ -401,8 +401,8 @@ bool L6470_Marlin::get_user_input(uint8_t &driver_count, uint8_t axis_index[3],
|
||||
} break;
|
||||
|
||||
case 'E': {
|
||||
position_min = center[E_AXIS] - displacement;
|
||||
position_max = center[E_AXIS] + displacement;
|
||||
position_min = center.e - displacement;
|
||||
position_max = center.e + displacement;
|
||||
echo_min_max('E', position_min, position_max);
|
||||
} break;
|
||||
}
|
||||
|
@ -65,6 +65,9 @@ inline void incremental_WLSF(struct linear_fit_data *lsf, const float &x, const
|
||||
lsf->max_absx = _MAX(ABS(wx), lsf->max_absx);
|
||||
lsf->max_absy = _MAX(ABS(wy), lsf->max_absy);
|
||||
}
|
||||
inline void incremental_WLSF(struct linear_fit_data *lsf, const xy_pos_t &pos, const float &z, const float &w) {
|
||||
incremental_WLSF(lsf, pos.x, pos.y, z, w);
|
||||
}
|
||||
|
||||
inline void incremental_LSF(struct linear_fit_data *lsf, const float &x, const float &y, const float &z) {
|
||||
lsf->xbar += x;
|
||||
@ -80,5 +83,8 @@ inline void incremental_LSF(struct linear_fit_data *lsf, const float &x, const f
|
||||
lsf->max_absy = _MAX(ABS(y), lsf->max_absy);
|
||||
lsf->N += 1.0;
|
||||
}
|
||||
inline void incremental_LSF(struct linear_fit_data *lsf, const xy_pos_t &pos, const float &z) {
|
||||
incremental_LSF(lsf, pos.x, pos.y, z);
|
||||
}
|
||||
|
||||
int finish_incremental_LSF(struct linear_fit_data *);
|
||||
|
@ -30,7 +30,6 @@ Nozzle nozzle;
|
||||
|
||||
#include "../Marlin.h"
|
||||
#include "../module/motion.h"
|
||||
#include "point_t.h"
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_FEATURE)
|
||||
|
||||
@ -38,30 +37,30 @@ Nozzle nozzle;
|
||||
* @brief Stroke clean pattern
|
||||
* @details Wipes the nozzle back and forth in a linear movement
|
||||
*
|
||||
* @param start point_t defining the starting point
|
||||
* @param end point_t defining the ending point
|
||||
* @param start xyz_pos_t defining the starting point
|
||||
* @param end xyz_pos_t defining the ending point
|
||||
* @param strokes number of strokes to execute
|
||||
*/
|
||||
void Nozzle::stroke(const point_t &start, const point_t &end, const uint8_t &strokes) {
|
||||
void Nozzle::stroke(const xyz_pos_t &start, const xyz_pos_t &end, const uint8_t &strokes) {
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
|
||||
const xyz_pos_t oldpos = current_position;
|
||||
#endif
|
||||
|
||||
// Move to the starting point
|
||||
#if ENABLED(NOZZLE_CLEAN_NO_Z)
|
||||
do_blocking_move_to_xy(start.x, start.y);
|
||||
do_blocking_move_to_xy(start);
|
||||
#else
|
||||
do_blocking_move_to(start.x, start.y, start.z);
|
||||
do_blocking_move_to(start);
|
||||
#endif
|
||||
|
||||
// Start the stroke pattern
|
||||
for (uint8_t i = 0; i < (strokes >> 1); i++) {
|
||||
do_blocking_move_to_xy(end.x, end.y);
|
||||
do_blocking_move_to_xy(start.x, start.y);
|
||||
do_blocking_move_to_xy(end);
|
||||
do_blocking_move_to_xy(start);
|
||||
}
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
do_blocking_move_to(ix, iy, iz);
|
||||
do_blocking_move_to(oldpos);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -69,29 +68,29 @@ Nozzle nozzle;
|
||||
* @brief Zig-zag clean pattern
|
||||
* @details Apply a zig-zag cleaning pattern
|
||||
*
|
||||
* @param start point_t defining the starting point
|
||||
* @param end point_t defining the ending point
|
||||
* @param start xyz_pos_t defining the starting point
|
||||
* @param end xyz_pos_t defining the ending point
|
||||
* @param strokes number of strokes to execute
|
||||
* @param objects number of triangles to do
|
||||
*/
|
||||
void Nozzle::zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) {
|
||||
const float diffx = end.x - start.x, diffy = end.y - start.y;
|
||||
if (!diffx || !diffy) return;
|
||||
void Nozzle::zigzag(const xyz_pos_t &start, const xyz_pos_t &end, const uint8_t &strokes, const uint8_t &objects) {
|
||||
const xy_pos_t diff = end - start;
|
||||
if (!diff.x || !diff.y) return;
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
|
||||
const xyz_pos_t back = current_position;
|
||||
#endif
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_NO_Z)
|
||||
do_blocking_move_to_xy(start.x, start.y);
|
||||
do_blocking_move_to_xy(start);
|
||||
#else
|
||||
do_blocking_move_to(start.x, start.y, start.z);
|
||||
do_blocking_move_to(start);
|
||||
#endif
|
||||
|
||||
const uint8_t zigs = objects << 1;
|
||||
const bool horiz = ABS(diffx) >= ABS(diffy); // Do a horizontal wipe?
|
||||
const float P = (horiz ? diffx : diffy) / zigs; // Period of each zig / zag
|
||||
const point_t *side;
|
||||
const bool horiz = ABS(diff.x) >= ABS(diff.y); // Do a horizontal wipe?
|
||||
const float P = (horiz ? diff.x : diff.y) / zigs; // Period of each zig / zag
|
||||
const xyz_pos_t *side;
|
||||
for (uint8_t j = 0; j < strokes; j++) {
|
||||
for (int8_t i = 0; i < zigs; i++) {
|
||||
side = (i & 1) ? &end : &start;
|
||||
@ -110,7 +109,7 @@ Nozzle nozzle;
|
||||
}
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
do_blocking_move_to(ix, iy, iz);
|
||||
do_blocking_move_to(back);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -118,21 +117,21 @@ Nozzle nozzle;
|
||||
* @brief Circular clean pattern
|
||||
* @details Apply a circular cleaning pattern
|
||||
*
|
||||
* @param start point_t defining the middle of circle
|
||||
* @param start xyz_pos_t defining the middle of circle
|
||||
* @param strokes number of strokes to execute
|
||||
* @param radius radius of circle
|
||||
*/
|
||||
void Nozzle::circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) {
|
||||
void Nozzle::circle(const xyz_pos_t &start, const xyz_pos_t &middle, const uint8_t &strokes, const float &radius) {
|
||||
if (strokes == 0) return;
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
const float ix = current_position[X_AXIS], iy = current_position[Y_AXIS], iz = current_position[Z_AXIS];
|
||||
const xyz_pos_t back = current_position;
|
||||
#endif
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_NO_Z)
|
||||
do_blocking_move_to_xy(start.x, start.y);
|
||||
do_blocking_move_to_xy(start);
|
||||
#else
|
||||
do_blocking_move_to(start.x, start.y, start.z);
|
||||
do_blocking_move_to(start);
|
||||
#endif
|
||||
|
||||
for (uint8_t s = 0; s < strokes; s++)
|
||||
@ -143,10 +142,10 @@ Nozzle nozzle;
|
||||
);
|
||||
|
||||
// Let's be safe
|
||||
do_blocking_move_to_xy(start.x, start.y);
|
||||
do_blocking_move_to_xy(start);
|
||||
|
||||
#if ENABLED(NOZZLE_CLEAN_GOBACK)
|
||||
do_blocking_move_to(ix, iy, iz);
|
||||
do_blocking_move_to(back);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -158,21 +157,21 @@ Nozzle nozzle;
|
||||
* @param argument depends on the cleaning pattern
|
||||
*/
|
||||
void Nozzle::clean(const uint8_t &pattern, const uint8_t &strokes, const float &radius, const uint8_t &objects, const uint8_t cleans) {
|
||||
point_t start = NOZZLE_CLEAN_START_POINT;
|
||||
point_t end = NOZZLE_CLEAN_END_POINT;
|
||||
xyz_pos_t start = NOZZLE_CLEAN_START_POINT, end = NOZZLE_CLEAN_END_POINT;
|
||||
|
||||
if (pattern == 2) {
|
||||
if (!(cleans & (_BV(X_AXIS) | _BV(Y_AXIS)))) {
|
||||
SERIAL_ECHOLNPGM("Warning : Clean Circle requires XY");
|
||||
return;
|
||||
}
|
||||
end = NOZZLE_CLEAN_CIRCLE_MIDDLE;
|
||||
constexpr xyz_pos_t middle NOZZLE_CLEAN_CIRCLE_MIDDLE;
|
||||
end = middle;
|
||||
}
|
||||
else {
|
||||
if (!TEST(cleans, X_AXIS)) start.x = end.x = current_position[X_AXIS];
|
||||
if (!TEST(cleans, Y_AXIS)) start.y = end.y = current_position[Y_AXIS];
|
||||
if (!TEST(cleans, X_AXIS)) start.x = end.x = current_position.x;
|
||||
if (!TEST(cleans, Y_AXIS)) start.y = end.y = current_position.y;
|
||||
}
|
||||
if (!TEST(cleans, Z_AXIS)) start.z = end.z = current_position[Z_AXIS];
|
||||
if (!TEST(cleans, Z_AXIS)) start.z = end.z = current_position.z;
|
||||
|
||||
switch (pattern) {
|
||||
case 1: zigzag(start, end, strokes, objects); break;
|
||||
@ -185,7 +184,7 @@ Nozzle nozzle;
|
||||
|
||||
#if ENABLED(NOZZLE_PARK_FEATURE)
|
||||
|
||||
void Nozzle::park(const uint8_t z_action, const point_t &park/*=NOZZLE_PARK_POINT*/) {
|
||||
void Nozzle::park(const uint8_t z_action, const xyz_pos_t &park/*=NOZZLE_PARK_POINT*/) {
|
||||
constexpr feedRate_t fr_xy = NOZZLE_PARK_XY_FEEDRATE, fr_z = NOZZLE_PARK_Z_FEEDRATE;
|
||||
|
||||
switch (z_action) {
|
||||
@ -194,14 +193,14 @@ Nozzle nozzle;
|
||||
break;
|
||||
|
||||
case 2: // Raise by Z-park height
|
||||
do_blocking_move_to_z(_MIN(current_position[Z_AXIS] + park.z, Z_MAX_POS), fr_z);
|
||||
do_blocking_move_to_z(_MIN(current_position.z + park.z, Z_MAX_POS), fr_z);
|
||||
break;
|
||||
|
||||
default: // Raise to at least the Z-park height
|
||||
do_blocking_move_to_z(_MAX(park.z, current_position[Z_AXIS]), fr_z);
|
||||
do_blocking_move_to_z(_MAX(park.z, current_position.z), fr_z);
|
||||
}
|
||||
|
||||
do_blocking_move_to_xy(park.x, park.y, fr_xy);
|
||||
do_blocking_move_to_xy(park, fr_xy);
|
||||
|
||||
report_current_position();
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "../inc/MarlinConfig.h"
|
||||
#include "point_t.h"
|
||||
|
||||
/**
|
||||
* @brief Nozzle class
|
||||
@ -38,32 +37,32 @@ class Nozzle {
|
||||
* @brief Stroke clean pattern
|
||||
* @details Wipes the nozzle back and forth in a linear movement
|
||||
*
|
||||
* @param start point_t defining the starting point
|
||||
* @param end point_t defining the ending point
|
||||
* @param start xyz_pos_t defining the starting point
|
||||
* @param end xyz_pos_t defining the ending point
|
||||
* @param strokes number of strokes to execute
|
||||
*/
|
||||
static void stroke(const point_t &start, const point_t &end, const uint8_t &strokes) _Os;
|
||||
static void stroke(const xyz_pos_t &start, const xyz_pos_t &end, const uint8_t &strokes) _Os;
|
||||
|
||||
/**
|
||||
* @brief Zig-zag clean pattern
|
||||
* @details Apply a zig-zag cleaning pattern
|
||||
*
|
||||
* @param start point_t defining the starting point
|
||||
* @param end point_t defining the ending point
|
||||
* @param start xyz_pos_t defining the starting point
|
||||
* @param end xyz_pos_t defining the ending point
|
||||
* @param strokes number of strokes to execute
|
||||
* @param objects number of objects to create
|
||||
*/
|
||||
static void zigzag(const point_t &start, const point_t &end, const uint8_t &strokes, const uint8_t &objects) _Os;
|
||||
static void zigzag(const xyz_pos_t &start, const xyz_pos_t &end, const uint8_t &strokes, const uint8_t &objects) _Os;
|
||||
|
||||
/**
|
||||
* @brief Circular clean pattern
|
||||
* @details Apply a circular cleaning pattern
|
||||
*
|
||||
* @param start point_t defining the middle of circle
|
||||
* @param start xyz_pos_t defining the middle of circle
|
||||
* @param strokes number of strokes to execute
|
||||
* @param radius radius of circle
|
||||
*/
|
||||
static void circle(const point_t &start, const point_t &middle, const uint8_t &strokes, const float &radius) _Os;
|
||||
static void circle(const xyz_pos_t &start, const xyz_pos_t &middle, const uint8_t &strokes, const float &radius) _Os;
|
||||
|
||||
#endif // NOZZLE_CLEAN_FEATURE
|
||||
|
||||
@ -84,7 +83,7 @@ class Nozzle {
|
||||
|
||||
#if ENABLED(NOZZLE_PARK_FEATURE)
|
||||
|
||||
static void park(const uint8_t z_action, const point_t &park=NOZZLE_PARK_POINT) _Os;
|
||||
static void park(const uint8_t z_action, const xyz_pos_t &park=NOZZLE_PARK_POINT) _Os;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
@ -1,55 +0,0 @@
|
||||
/**
|
||||
* Marlin 3D Printer Firmware
|
||||
* Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
|
||||
*
|
||||
* Based on Sprinter and grbl.
|
||||
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* @brief Cartesian Point
|
||||
* @details Represents a three dimensional point on Cartesian coordinate system,
|
||||
* using an additional fourth dimension for the extrusion length.
|
||||
*
|
||||
* @param x The x-coordinate of the point.
|
||||
* @param y The y-coordinate of the point.
|
||||
* @param z The z-coordinate of the point.
|
||||
*/
|
||||
struct point_t {
|
||||
float x, y, z;
|
||||
|
||||
/**
|
||||
* @brief Three dimensional point constructor
|
||||
*
|
||||
* @param x The x-coordinate of the point.
|
||||
* @param y The y-coordinate of the point.
|
||||
* @param z The z-coordinate of the point.
|
||||
*/
|
||||
point_t(const float x, const float y, const float z) : x(x), y(y), z(z) {}
|
||||
|
||||
/**
|
||||
* @brief Two dimensional point constructor
|
||||
*
|
||||
* @param x The x-coordinate of the point.
|
||||
* @param y The y-coordinate of the point.
|
||||
*/
|
||||
point_t(const float x, const float y) : point_t(x, y, NAN) {}
|
||||
|
||||
};
|
@ -47,81 +47,74 @@
|
||||
|
||||
#include <math.h>
|
||||
|
||||
vector_3::vector_3() : x(0), y(0), z(0) { }
|
||||
|
||||
vector_3::vector_3(float x_, float y_, float z_) : x(x_), y(y_), z(z_) { }
|
||||
/**
|
||||
* vector_3
|
||||
*/
|
||||
|
||||
vector_3 vector_3::cross(const vector_3 &left, const vector_3 &right) {
|
||||
return vector_3(left.y * right.z - left.z * right.y,
|
||||
left.z * right.x - left.x * right.z,
|
||||
left.x * right.y - left.y * right.x);
|
||||
const xyz_float_t &lv = left, &rv = right;
|
||||
return vector_3(lv.y * rv.z - lv.z * rv.y, // YZ cross
|
||||
lv.z * rv.x - lv.x * rv.z, // ZX cross
|
||||
lv.x * rv.y - lv.y * rv.x); // XY cross
|
||||
}
|
||||
|
||||
vector_3 vector_3::operator+(const vector_3 &v) { return vector_3(x + v.x, y + v.y, z + v.z); }
|
||||
vector_3 vector_3::operator-(const vector_3 &v) { return vector_3(x - v.x, y - v.y, z - v.z); }
|
||||
|
||||
vector_3 vector_3::operator* (const float &v) { return vector_3(x * v, y * v, z * v); }
|
||||
vector_3& vector_3::operator*=(const float &v) { x *= v; y *= v; z *= v; return *this; }
|
||||
|
||||
vector_3 vector_3::get_normal() const {
|
||||
vector_3 normalized = vector_3(x, y, z);
|
||||
vector_3 normalized = *this;
|
||||
normalized.normalize();
|
||||
return normalized;
|
||||
}
|
||||
|
||||
float vector_3::get_length() const { return SQRT(sq(x) + sq(y) + sq(z)); }
|
||||
|
||||
void vector_3::normalize() {
|
||||
const float inv_length = RSQRT(sq(x) + sq(y) + sq(z));
|
||||
x *= inv_length;
|
||||
y *= inv_length;
|
||||
z *= inv_length;
|
||||
*this *= RSQRT(sq(x) + sq(y) + sq(z));
|
||||
}
|
||||
|
||||
// Apply a rotation to the matrix
|
||||
void vector_3::apply_rotation(const matrix_3x3 &matrix) {
|
||||
const float _x = x, _y = y;
|
||||
x = _x * matrix.matrix[3 * 0 + 0] + _y * matrix.matrix[3 * 1 + 0] + z * matrix.matrix[3 * 2 + 0];
|
||||
y = _x * matrix.matrix[3 * 0 + 1] + _y * matrix.matrix[3 * 1 + 1] + z * matrix.matrix[3 * 2 + 1];
|
||||
z = _x * matrix.matrix[3 * 0 + 2] + _y * matrix.matrix[3 * 1 + 2] + z * matrix.matrix[3 * 2 + 2];
|
||||
const float _x = x, _y = y, _z = z;
|
||||
*this = matrix.vectors[0] * _x + matrix.vectors[1] * _y + matrix.vectors[2] * _z;
|
||||
}
|
||||
|
||||
void vector_3::debug(PGM_P const title) {
|
||||
serialprintPGM(title);
|
||||
SERIAL_ECHOPAIR_F(" x: ", x, 6);
|
||||
SERIAL_ECHOPAIR_F(" y: ", y, 6);
|
||||
SERIAL_ECHOLNPAIR_F(" z: ", z, 6);
|
||||
SERIAL_ECHOPAIR_F(" X", x, 6);
|
||||
SERIAL_ECHOPAIR_F(" Y", y, 6);
|
||||
SERIAL_ECHOLNPAIR_F(" Z", z, 6);
|
||||
}
|
||||
|
||||
void apply_rotation_xyz(const matrix_3x3 &matrix, float &x, float &y, float &z) {
|
||||
vector_3 vector = vector_3(x, y, z);
|
||||
vector.apply_rotation(matrix);
|
||||
x = vector.x;
|
||||
y = vector.y;
|
||||
z = vector.z;
|
||||
/**
|
||||
* matrix_3x3
|
||||
*/
|
||||
|
||||
void apply_rotation_xyz(const matrix_3x3 &matrix, float &_x, float &_y, float &_z) {
|
||||
vector_3 vec = vector_3(_x, _y, _z); vec.apply_rotation(matrix);
|
||||
_x = vec.x; _y = vec.y; _z = vec.z;
|
||||
}
|
||||
|
||||
// Reset to identity. No rotate or translate.
|
||||
void matrix_3x3::set_to_identity() {
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
for (uint8_t j = 0; j < 3; j++)
|
||||
vectors[i][j] = float(i == j);
|
||||
}
|
||||
|
||||
// Create a matrix from 3 vector_3 inputs
|
||||
matrix_3x3 matrix_3x3::create_from_rows(const vector_3 &row_0, const vector_3 &row_1, const vector_3 &row_2) {
|
||||
//row_0.debug(PSTR("row_0"));
|
||||
//row_1.debug(PSTR("row_1"));
|
||||
//row_2.debug(PSTR("row_2"));
|
||||
matrix_3x3 new_matrix;
|
||||
new_matrix.matrix[0] = row_0.x; new_matrix.matrix[1] = row_0.y; new_matrix.matrix[2] = row_0.z;
|
||||
new_matrix.matrix[3] = row_1.x; new_matrix.matrix[4] = row_1.y; new_matrix.matrix[5] = row_1.z;
|
||||
new_matrix.matrix[6] = row_2.x; new_matrix.matrix[7] = row_2.y; new_matrix.matrix[8] = row_2.z;
|
||||
new_matrix.vectors[0] = row_0;
|
||||
new_matrix.vectors[1] = row_1;
|
||||
new_matrix.vectors[2] = row_2;
|
||||
//new_matrix.debug(PSTR("new_matrix"));
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
void matrix_3x3::set_to_identity() {
|
||||
matrix[0] = 1; matrix[1] = 0; matrix[2] = 0;
|
||||
matrix[3] = 0; matrix[4] = 1; matrix[5] = 0;
|
||||
matrix[6] = 0; matrix[7] = 0; matrix[8] = 1;
|
||||
}
|
||||
|
||||
// Create a matrix rotated to point towards a target
|
||||
matrix_3x3 matrix_3x3::create_look_at(const vector_3 &target) {
|
||||
vector_3 z_row = target.get_normal(),
|
||||
x_row = vector_3(1, 0, -target.x / target.z).get_normal(),
|
||||
y_row = vector_3::cross(z_row, x_row).get_normal();
|
||||
const vector_3 z_row = target.get_normal(),
|
||||
x_row = vector_3(1, 0, -target.x / target.z).get_normal(),
|
||||
y_row = vector_3::cross(z_row, x_row).get_normal();
|
||||
|
||||
// x_row.debug(PSTR("x_row"));
|
||||
// y_row.debug(PSTR("y_row"));
|
||||
@ -134,11 +127,12 @@ matrix_3x3 matrix_3x3::create_look_at(const vector_3 &target) {
|
||||
return rot;
|
||||
}
|
||||
|
||||
// Get a transposed copy of the matrix
|
||||
matrix_3x3 matrix_3x3::transpose(const matrix_3x3 &original) {
|
||||
matrix_3x3 new_matrix;
|
||||
new_matrix.matrix[0] = original.matrix[0]; new_matrix.matrix[1] = original.matrix[3]; new_matrix.matrix[2] = original.matrix[6];
|
||||
new_matrix.matrix[3] = original.matrix[1]; new_matrix.matrix[4] = original.matrix[4]; new_matrix.matrix[5] = original.matrix[7];
|
||||
new_matrix.matrix[6] = original.matrix[2]; new_matrix.matrix[7] = original.matrix[5]; new_matrix.matrix[8] = original.matrix[8];
|
||||
for (uint8_t i = 0; i < 3; i++)
|
||||
for (uint8_t j = 0; j < 3; j++)
|
||||
new_matrix.vectors[i][j] = original.vectors[j][i];
|
||||
return new_matrix;
|
||||
}
|
||||
|
||||
@ -147,13 +141,11 @@ void matrix_3x3::debug(PGM_P const title) {
|
||||
serialprintPGM(title);
|
||||
SERIAL_EOL();
|
||||
}
|
||||
uint8_t count = 0;
|
||||
for (uint8_t i = 0; i < 3; i++) {
|
||||
for (uint8_t j = 0; j < 3; j++) {
|
||||
if (matrix[count] >= 0.0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO_F(matrix[count], 6);
|
||||
if (vectors[i][j] >= 0.0) SERIAL_CHAR('+');
|
||||
SERIAL_ECHO_F(vectors[i][j], 6);
|
||||
SERIAL_CHAR(' ');
|
||||
count++;
|
||||
}
|
||||
SERIAL_EOL();
|
||||
}
|
||||
|
@ -40,33 +40,40 @@
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "../core/types.h"
|
||||
|
||||
class matrix_3x3;
|
||||
|
||||
struct vector_3 {
|
||||
float x, y, z;
|
||||
struct vector_3 : xyz_float_t {
|
||||
|
||||
vector_3();
|
||||
vector_3(float x, float y, float z);
|
||||
vector_3(const float &_x, const float &_y, const float &_z) { set(_x, _y, _z); }
|
||||
vector_3(const xy_float_t &in) { set(in.x, in.y); }
|
||||
vector_3(const xyz_float_t &in) { set(in.x, in.y, in.z); }
|
||||
vector_3(const xyze_float_t &in) { set(in.x, in.y, in.z); }
|
||||
|
||||
// Factory method
|
||||
static vector_3 cross(const vector_3 &a, const vector_3 &b);
|
||||
|
||||
vector_3 operator+(const vector_3 &v);
|
||||
vector_3 operator-(const vector_3 &v);
|
||||
|
||||
vector_3 operator* (const float &v);
|
||||
vector_3& operator*=(const float &v);
|
||||
|
||||
// Modifiers
|
||||
void normalize();
|
||||
void apply_rotation(const matrix_3x3 &matrix);
|
||||
|
||||
// Accessors
|
||||
float get_length() const;
|
||||
vector_3 get_normal() const;
|
||||
|
||||
// Operators
|
||||
FORCE_INLINE vector_3 operator+(const vector_3 &v) const { vector_3 o = *this; o += v; return o; }
|
||||
FORCE_INLINE vector_3 operator-(const vector_3 &v) const { vector_3 o = *this; o -= v; return o; }
|
||||
FORCE_INLINE vector_3 operator*(const float &v) const { vector_3 o = *this; o *= v; return o; }
|
||||
|
||||
void debug(PGM_P const title);
|
||||
void apply_rotation(const matrix_3x3 &matrix);
|
||||
};
|
||||
|
||||
struct matrix_3x3 {
|
||||
float matrix[9];
|
||||
abc_float_t vectors[3];
|
||||
|
||||
// Factory methods
|
||||
static matrix_3x3 create_from_rows(const vector_3 &row_0, const vector_3 &row_1, const vector_3 &row_2);
|
||||
static matrix_3x3 create_look_at(const vector_3 &target);
|
||||
static matrix_3x3 transpose(const matrix_3x3 &original);
|
||||
@ -76,5 +83,7 @@ struct matrix_3x3 {
|
||||
void debug(PGM_P const title);
|
||||
};
|
||||
|
||||
|
||||
void apply_rotation_xyz(const matrix_3x3 &rotationMatrix, float &x, float &y, float &z);
|
||||
FORCE_INLINE void apply_rotation_xyz(const matrix_3x3 &rotationMatrix, xyz_pos_t &pos) {
|
||||
apply_rotation_xyz(rotationMatrix, pos.x, pos.y, pos.z);
|
||||
}
|
||||
|
Reference in New Issue
Block a user