[python/turtle] Store the heading in degrees with no k_headingOffset

This reduces rouding errors, such as:
setHeading(0)
right(1)
heading() -> gives -1.00...01
This commit is contained in:
Léa Saviot
2019-01-15 13:58:57 +01:00
committed by EmilieNumworks
parent 6948de2ad3
commit 2f9f40f1a7
2 changed files with 13 additions and 24 deletions

View File

@@ -31,7 +31,7 @@ void Turtle::reset() {
// Reset turtle values
m_x = 0;
m_y = 0;
m_heading = k_headingOffset;
m_heading = 0;
m_color = k_defaultColor;
m_penDown = true;
m_visible = true;
@@ -45,20 +45,18 @@ void Turtle::reset() {
bool Turtle::forward(mp_float_t length) {
return goTo(
m_x + length * sin(m_heading),
m_y + length * cos(m_heading)
m_x + length * cos(m_heading * k_headingScale),
m_y + length * sin(m_heading * k_headingScale)
);
}
void Turtle::left(mp_float_t angle) {
setHeading(
k_invertedYAxisCoefficient * ((m_heading - k_headingOffset) + k_invertedYAxisCoefficient * (angle * k_headingScale)) / k_headingScale
);
setHeading(m_heading + angle);
}
void Turtle::circle(mp_int_t radius, mp_float_t angle) {
mp_float_t oldHeading = heading();
mp_float_t length = ((angle > 0 ? 1 : -1) * angle * k_headingScale) * radius;
mp_float_t length = (angle > 0 ? 1 : -1) * angle * k_headingScale * radius;
if (length > 1) {
for (int i = 1; i < length; i++) {
mp_float_t progress = i / length;
@@ -99,10 +97,6 @@ bool Turtle::goTo(mp_float_t x, mp_float_t y) {
return false;
}
mp_float_t Turtle::heading() const {
return k_invertedYAxisCoefficient * (m_heading - k_headingOffset) / k_headingScale;
}
void Turtle::setHeading(mp_float_t angle) {
micropython_port_vm_hook_loop();
setHeadingPrivate(angle);
@@ -173,10 +167,6 @@ void Turtle::viewDidDisappear() {
// Private functions
void Turtle::setHeadingPrivate(mp_float_t angle) {
m_heading = k_invertedYAxisCoefficient * angle * k_headingScale + k_headingOffset;
}
KDPoint Turtle::position(mp_float_t x, mp_float_t y) const {
return KDPoint(floor(x + k_xOffset), floor(k_invertedYAxisCoefficient * y + k_yOffset));
}
@@ -245,8 +235,8 @@ bool Turtle::draw(bool force) {
// Draw the head
KDCoordinate headOffsetLength = 6;
KDCoordinate headOffsetX = headOffsetLength * sin(m_heading);
KDCoordinate headOffsetY = -headOffsetLength * cos(m_heading);
KDCoordinate headOffsetX = headOffsetLength * cos(m_heading * k_headingScale);
KDCoordinate headOffsetY = k_invertedYAxisCoefficient * headOffsetLength * sin(m_heading * k_headingScale);
KDPoint headOffset(headOffsetX, headOffsetY);
drawingRect = KDRect(
position().translatedBy(headOffset).translatedBy(KDPoint(-k_iconHeadSize/2, -k_iconHeadSize/2)),
@@ -336,8 +326,8 @@ void Turtle::drawPaw(PawType type, PawPosition pos) {
// Compute the paw offset from the turtle center
float currentAngle = angles[(int) type];
float crawlDelta = ((float)((int)pos)) * crawlOffset;
float pawX = pawOffset * sin(m_heading+currentAngle) + crawlDelta * sin(m_heading);
float pawY = - pawOffset * cos(m_heading+currentAngle) - crawlDelta * cos(m_heading);
float pawX = pawOffset * cos(m_heading * k_headingScale + currentAngle) + crawlDelta * cos(m_heading * k_headingScale);
float pawY = k_invertedYAxisCoefficient * (pawOffset * sin(m_heading * k_headingScale + currentAngle) + crawlDelta * sin(m_heading * k_headingScale));
KDCoordinate pawOffsetX = ((int)pawX) - (pawX < 0 ? 1 : 0);
KDCoordinate pawOffsetY = ((int)pawY) - (pawY < 0 ? 1 : 0);
KDPoint offset(pawOffsetX, pawOffsetY);

View File

@@ -24,7 +24,7 @@ public:
constexpr Turtle() :
m_x(0),
m_y(0),
m_heading(k_headingOffset),
m_heading(0),
m_color(k_defaultColor),
m_penDown(true),
m_visible(true),
@@ -47,7 +47,7 @@ public:
void circle(mp_int_t radius, mp_float_t angle = 360);
bool goTo(mp_float_t x, mp_float_t y);
mp_float_t heading() const;
mp_float_t heading() const { return m_heading; }
void setHeading(mp_float_t angle);
uint8_t speed() const { return m_speed; }
@@ -76,7 +76,6 @@ public:
void viewDidDisappear();
private:
static constexpr mp_float_t k_headingOffset = M_PI_2;
static constexpr mp_float_t k_headingScale = M_PI / 180;
/* The Y axis is oriented upwards in Turtle and downwards in Kandinsky, so we
* need to invert some values, hence k_invertedYAxisCoefficient. */
@@ -116,7 +115,7 @@ private:
KDColor m_color;
};
void setHeadingPrivate(mp_float_t angle);
void setHeadingPrivate(mp_float_t angle) { m_heading = angle; }
KDPoint position(mp_float_t x, mp_float_t y) const;
KDPoint position() const { return position(m_x, m_y); }
@@ -137,7 +136,7 @@ private:
* right and the y axis goes upwards. */
mp_float_t m_x;
mp_float_t m_y;
/* The heading is the angle in radians between the direction of the turtle and
/* The heading is the angle in degrees between the direction of the turtle and
* the X axis, in the counterclockwise direction. */
mp_float_t m_heading;