Prusa MINI Firmware overview
bresenham.h
Go to the documentation of this file.
1 /**
2  * Marlin 3D Printer Firmware
3  * Copyright (c) 2019 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
4  *
5  * Based on Sprinter and grbl.
6  * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 #pragma once
23 
24 #include "../core/serial.h"
25 
26 /**
27  * bresenham_t.h - Bresenham algorithm template
28  *
29  * An array of values / counters that tick together
30  */
31 
32 #define FORCE_INLINE __attribute__((always_inline)) inline
33 #define _O3 __attribute__((optimize("O3")))
34 
35 template <uint8_t uid, uint8_t size>
36 struct BresenhamCfg { static constexpr uint8_t UID = uid, SIZE = size; };
37 
38 template<typename T, typename Cfg>
39 class Bresenham {
40 private:
41 
42  static constexpr T signtest = -1;
43  static_assert(signtest < 0, "Bresenham type must be signed!");
44 
45 public:
46 
47  static T divisor, value[Cfg::SIZE], dir[Cfg::SIZE], dividend[Cfg::SIZE], counter[Cfg::SIZE];
48 
49  // Default: Instantiate all items with the identical parameters
50  Bresenham(const T &inDivisor=1, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0) {
51  for (uint8_t i = 0; i < Cfg::SIZE; i++) init(i, inDivisor, inDir, inDividend, inValue);
52  }
53 
54  // Instantiate all items with the same divisor
55  Bresenham(const T &inDivisor, const int8_t (&inDir)[Cfg::SIZE], const T (&inDividend)[Cfg::SIZE], const T (&inValue)[Cfg::SIZE]={0}) {
56  init(inDivisor, inDir, inDividend, inValue);
57  }
58 
59  // Instantiate all items with the same divisor and direction
60  Bresenham(const T &inDivisor, const int8_t &inDir, const T (&inDividend)[Cfg::SIZE], const T (&inValue)[Cfg::SIZE]={0}) {
61  init(inDivisor, inDir, inDividend, inValue);
62  }
63 
64  // Init all items with the same parameters
65  FORCE_INLINE static void init(const uint8_t index, const T &inDivisor=1, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0) {
66  divisor = inDivisor;
67  dir[index] = inDir;
68  dividend[index] = inDividend;
69  value[index] = inValue;
70  prime(index);
71  }
72 
73  // Init all items with the same divisor
74  FORCE_INLINE static void init(const T &inDivisor, const int8_t (&inDir)[Cfg::SIZE], const T (&inDividend)[Cfg::SIZE], const T (&inValue)[Cfg::SIZE]={0}) {
75  divisor = inDivisor;
76  for (uint8_t i = 0; i < Cfg::SIZE; i++) {
77  dir[i] = inDir[i];
78  dividend[i] = inDividend[i];
79  value[i] = inValue[i];
80  }
81  prime();
82  }
83 
84  // Init all items with the same divisor and direction
85  FORCE_INLINE static void init(const T &inDivisor, const int8_t &inDir, const T (&inDividend)[Cfg::SIZE], const T (&inValue)[Cfg::SIZE]={0}) {
86  divisor = inDivisor;
87  for (uint8_t i = 0; i < Cfg::SIZE; i++) {
88  dir[i] = inDir;
89  dividend[i] = inDividend[i];
90  value[i] = inValue[i];
91  }
92  prime();
93  }
94 
95  // Reinit item with new dir, dividend, value keeping the same divisor
96  FORCE_INLINE static void reinit(const uint8_t index, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0) {
97  dir[index] = inDir;
98  dividend[index] = inDividend;
99  value[index] = inValue;
100  prime();
101  }
102 
103  FORCE_INLINE static void prime(const uint8_t index) { counter[index] = -(divisor / 2); }
104  FORCE_INLINE static void prime() { for (uint8_t i = 0; i < Cfg::SIZE; i++) prime(i); }
105 
106  FORCE_INLINE static void back(const uint8_t index) { counter[index] -= divisor; }
107 
108  FORCE_INLINE static bool tick1(const uint8_t index) {
109  counter[index] += dividend[index];
110  return counter[index] > 0;
111  }
112 
113  FORCE_INLINE static void tick(const uint8_t index) {
114  if (tick1(index)) { value[index] += dir[index]; back(index); }
115  }
116 
117  FORCE_INLINE static void tick1() _O3 { for (uint8_t i = 0; i < Cfg::SIZE; i++) (void)tick1(i); }
118 
119  FORCE_INLINE static void tick() _O3 { for (uint8_t i = 0; i < Cfg::SIZE; i++) (void)tick(i); }
120 
121  static void report(const uint8_t index) {
122  if (index < Cfg::SIZE) {
123  SERIAL_ECHOPAIR("bresenham ", int(index), " : (", dividend[index], "/", divisor, ") ");
124  if (counter[index] >= 0) SERIAL_CHAR(' ');
125  if (labs(counter[index]) < 100) { SERIAL_CHAR(' '); if (labs(counter[index]) < 10) SERIAL_CHAR(' '); }
126  SERIAL_ECHO(counter[index]);
127  SERIAL_ECHOLNPAIR(" ... ", value[index]);
128  }
129  }
130 
131  static void report() { for (uint8_t i = 0; i < Cfg::SIZE; i++) report(i); }
132 };
_O3
#define _O3
Definition: bresenham.h:33
Bresenham::tick1
static FORCE_INLINE bool tick1(const uint8_t index)
Definition: bresenham.h:108
SERIAL_CHAR
#define SERIAL_CHAR(x)
Definition: serial.h:69
SERIAL_ECHO
#define SERIAL_ECHO(x)
Definition: serial.h:70
Bresenham::init
static FORCE_INLINE void init(const T &inDivisor, const int8_t(&inDir)[Cfg::SIZE], const T(&inDividend)[Cfg::SIZE], const T(&inValue)[Cfg::SIZE]={0})
Definition: bresenham.h:74
SERIAL_ECHOPAIR
#define SERIAL_ECHOPAIR(V...)
Definition: serial.h:114
Bresenham::dividend
static T dividend[Cfg::SIZE]
Definition: bresenham.h:43
i
uint8_t i
Definition: screen_test_graph.c:72
BresenhamCfg::UID
static constexpr uint8_t UID
Definition: bresenham.h:36
Bresenham::report
static void report(const uint8_t index)
Definition: bresenham.h:121
Bresenham::value
static T value[Cfg::SIZE]
Definition: bresenham.h:43
Bresenham::Bresenham
Bresenham(const T &inDivisor=1, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0)
Definition: bresenham.h:50
Bresenham::counter
static T counter[Cfg::SIZE]
Definition: bresenham.h:43
Bresenham::tick
static FORCE_INLINE void tick() _O3
Definition: bresenham.h:119
Bresenham::tick1
static FORCE_INLINE void tick1() _O3
Definition: bresenham.h:117
Bresenham::prime
static FORCE_INLINE void prime(const uint8_t index)
Definition: bresenham.h:103
Bresenham::tick
static FORCE_INLINE void tick(const uint8_t index)
Definition: bresenham.h:113
Bresenham::divisor
static T divisor
Definition: bresenham.h:43
Bresenham::dir
static T dir[Cfg::SIZE]
Definition: bresenham.h:43
SERIAL_ECHOLNPAIR
#define SERIAL_ECHOLNPAIR(V...)
Definition: serial.h:144
uint8_t
const uint8_t[]
Definition: 404_html.c:3
Bresenham::Bresenham
Bresenham(const T &inDivisor, const int8_t &inDir, const T(&inDividend)[Cfg::SIZE], const T(&inValue)[Cfg::SIZE]={0})
Definition: bresenham.h:60
Bresenham::report
static void report()
Definition: bresenham.h:131
Bresenham::back
static FORCE_INLINE void back(const uint8_t index)
Definition: bresenham.h:106
Bresenham::prime
static FORCE_INLINE void prime()
Definition: bresenham.h:104
BresenhamCfg
Definition: bresenham.h:36
Bresenham::init
static FORCE_INLINE void init(const T &inDivisor, const int8_t &inDir, const T(&inDividend)[Cfg::SIZE], const T(&inValue)[Cfg::SIZE]={0})
Definition: bresenham.h:85
Bresenham::reinit
static FORCE_INLINE void reinit(const uint8_t index, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0)
Definition: bresenham.h:96
BresenhamCfg::SIZE
static constexpr uint8_t SIZE
Definition: bresenham.h:36
FORCE_INLINE
#define FORCE_INLINE
Definition: bresenham.h:32
Bresenham
Definition: bresenham.h:39
Bresenham::init
static FORCE_INLINE void init(const uint8_t index, const T &inDivisor=1, const int8_t &inDir=1, const T &inDividend=1, const T &inValue=0)
Definition: bresenham.h:65
Bresenham::Bresenham
Bresenham(const T &inDivisor, const int8_t(&inDir)[Cfg::SIZE], const T(&inDividend)[Cfg::SIZE], const T(&inValue)[Cfg::SIZE]={0})
Definition: bresenham.h:55
size
static png_bytep size_t size
Definition: pngwrite.c:2170