W
lord-maricek schrieb:
Ok, danke schonmal.
Ich habe gerade den Bresenham Algorithmus gefunden. Ich habe leider weder in Mathe noch beim Programmieren damit gearbeitet.
Du könntest einfach in 1/1000 rechnen. Ich nehme an, die Einheit der Längen ist mm, so müsstest Du halt in μm rechnen.
Es ist aber hier gar nicht nötig; der Bresenham Algorithmus wurde entwickelt um Graphik schneller zu machen. Deine CNC-Fräse wird nie so schnell sein, dass ein 0815-PC von heute da nicht mitkommt, auch wenn er für jeden μm einen neuen Wert berechnen musst. Auch ist der Bresenham Algorithmus nicht dafür geeignet eine CNC-Fräse zu steuern, da die absolute Schrittweite sich mit der Schrittrichtung um bis zu 41% ändern würde. Das ist sicher nicht erwünscht.
Besser Du bleibst bei float (oder besser Datentyp double) und rechnest weiter in mm.
brotbernd hat Dir schon die notwendigen Informationen gegeben. Hilfreich ist eine Klasse Point bzw. Vektor (im mathematischen Sinne), Beispiele für Vektor in C++ gibt es genug, dann sähe das etwa so aus:
#include <iostream>
#include <iomanip> // setprecision
#include <cmath> // std::sqrt
class Vektor
{
public:
Vektor() : m_x(0), m_y(0) {}
Vektor( double x, double y )
: m_x(x), m_y(y)
{}
Vektor& operator+=( const Vektor& b )
{
m_x += b.m_x; m_y += b.m_y;
return *this;
}
Vektor& operator-=( const Vektor& b )
{
m_x -= b.m_x; m_y -= b.m_y;
return *this;
}
Vektor& operator*=( double fac )
{
m_x *= fac; m_y *= fac;
return *this;
}
Vektor& operator/=( double div )
{
return *this *= 1/div;
}
// -- Länge
friend double abs( const Vektor& v )
{
return std::sqrt( v.m_x * v.m_x + v.m_y * v.m_y );
}
// -- Access
friend double X( const Vektor& v ) { return v.m_x; }
friend double Y( const Vektor& v ) { return v.m_y; }
// -- Ausgabe
friend std::ostream& operator<<( std::ostream& out, const Vektor& v )
{
return out << "(" << v.m_x << "|" << v.m_y << ")";
}
private:
double m_x, m_y;
};
Vektor operator+( Vektor a, const Vektor& b )
{
return a += b;
}
Vektor operator-( Vektor a, const Vektor& b )
{
return a -= b;
}
Vektor operator*( Vektor v, double fac )
{
return v *= fac;
}
Vektor operator*( double fac, Vektor v )
{
return v *= fac;
}
Vektor operator/( Vektor v, double div )
{
return v /= div;
}
int main()
{
using namespace std;
const double schrittweite = 1./1000; // 1/1000 mm
Vektor start( 15.002, 9.982 );
Vektor ende( 18.329, 24.691 );
Vektor richtung = ende - start;
int anzSchritte = int( abs( richtung ) / schrittweite + 0.5 ); // + 0.5 dient der korrekten Rundung
Vektor schritt = richtung / anzSchritte; // ein Schritt mit der Länge 'schrittweite'
cout << fixed << setprecision(3); // sorgt dafür, dass die double mit 3 Nachkommastellen geschrieben werden
int i = 0;
for( Vektor pos = start; i <= anzSchritte; ++i, pos = start + i*schritt )
{
cout << pos << endl;
}
return 0;
}
Ich habe die komplette Implementierung von Vektor auch gepostet, da ist jetzt auch nichts besonderes dabei. Du solltest zunächst versuchen zu verstehen, was im main passiert.
Wichtig bei der Realisierung ist noch, dass Du keine Fließkommazahlen aufsummierst, weil das sonst zu Rundungsfehlern führt. Deshalb auch der int in der Schleife.
Die Ausgabe ist:
(15.002|9.982)
(15.002|9.983)
(15.002|9.984)
(15.003|9.985)
(15.003|9.986)
(15.003|9.987)
(15.003|9.988)
(15.004|9.989)
(15.004|9.990)
(15.004|9.991)
...
(18.327|24.682)
(18.327|24.683)
(18.327|24.684)
(18.328|24.685)
(18.328|24.686)
(18.328|24.687)
(18.328|24.688)
(18.329|24.689)
(18.329|24.690)
(18.329|24.691)
Das sollte das sein, was Du gewünscht hast.
Gruß
Werner
@Edit: Referenz bei operator= vergessen