Exemple #1
0
        private HPGLElemente.Linie ErsteLinie(UInt16 Stift)
        {
            double KleinsterAbstand    = Double.MaxValue;
            double AktuellerAbstand    = 0D;
            bool   ErsteLinieRückwärts = false;

            HPGLElemente.Linie ersteLinie = null;

            if (_Linien == null || _Linien.Count == 0)
            {
                PlotterCom.StaticLogger.Log("Kann keine erste Linie ermitteln, Linien sind leer oder null!", 4);
                return(null);
            }


            // Irgendwas sollte drin stehen, auch wenn aufgrund des Stiftes keine passende Linie gefunden wird.
            ersteLinie = _Linien[0];

            foreach (HPGLElemente.Linie aktuelleLinie in _Linien)
            {
                if (aktuelleLinie.Pen != Stift)
                {
                    continue;
                }

                AktuellerAbstand = (aktuelleLinie.StartX * aktuelleLinie.StartX) +
                                   (aktuelleLinie.StartY + aktuelleLinie.StartY);

                if (AktuellerAbstand < KleinsterAbstand)
                {
                    KleinsterAbstand    = AktuellerAbstand;
                    ErsteLinieRückwärts = false;
                    ersteLinie          = aktuelleLinie;
                }

                AktuellerAbstand = (aktuelleLinie.EndX * aktuelleLinie.EndX) +
                                   (aktuelleLinie.EndY + aktuelleLinie.EndY);

                if (AktuellerAbstand < KleinsterAbstand)
                {
                    KleinsterAbstand    = AktuellerAbstand;
                    ErsteLinieRückwärts = true;
                    ersteLinie          = aktuelleLinie;
                }
            }

            if (ErsteLinieRückwärts)
            {
                ersteLinie.DreheUm();
            }

            return(ersteLinie);
        }
Exemple #2
0
        public void Optimiere(ToolStripProgressBar progressBar, ToolStripLabel label)
        {
            List <HPGLElemente.Linie> optimierteListe = null; // Die neue, optimierte Liste.
            List <UInt16>             StiftListe      = null; // Die Liste aller verwendeten Stifte.
            double kleinsterAbstand;                          // Der kleinste Abstand, der bisher gefunden wurde.
            double aktuellerAbstandV = 0D;                    // Temporäre Variable zum halten des aktuellen Abstands vorwärts.
            double aktuellerAbstandR = 0D;                    // Temporäre Variable zum halten des aktuellen Abstands rückwärts.
            bool   LinieRückwärts    = false;                 // Ist true, wenn die aktuelle Linie umgedreht werden muss.
            bool   LinieGefunden     = true;                  // Habe ich eine Line gefunden?

            HPGLElemente.Linie besteLinie             = null; // Die aktuell beste Linie.
            HPGLElemente.Linie zuletztOptimierteLinie = null; // Die Linie, ab deren Ende gesucht wird.

            if ((_Linien == null) || (_Linien.Count == 0))
            {
                PlotterCom.StaticLogger.Log("Keine Linien zum Optimieren. Ende", 4);
                return;
            }

            // Erstelle Liste mit allen verwendeten Stiften.
            StiftListe = StiftListeErstellen();

            // Fals die letzte Optimierung abgebrochen wurde, setzte OptimierenAbbrechen wieder auf false.
            OptimierenAbbrechen = false;

            // Erstelle eine neue, leere Liste in der die optimierte Liste aufgebaut wird.
            optimierteListe = new List <HPGLElemente.Linie>(_Linien.Count);

            // Zuerst das optimiert-Kennzeichen zurück setzen!
            foreach (HPGLElemente.Linie aktuelleLinie in _Linien)
            {
                aktuelleLinie.Optimiert = false;
            }

            // Das erste Element suchen und einfügen;
            optimierteListe.Add(ErsteLinie(StiftListe[0]));
            optimierteListe[0].Optimiert = true;
            zuletztOptimierteLinie       = optimierteListe[0];

            foreach (UInt16 AktuellerStift in StiftListe)
            {
                // Zum hereinspringen in die Schleife LinieGefunden erstmal auf true setzen.
                LinieGefunden = true;

                // Solange noch neue Linien gefunden werden...
                while (LinieGefunden)
                {
                    kleinsterAbstand = System.Double.MaxValue;

                    LinieRückwärts = false;
                    LinieGefunden  = false; // Wird true gesetzt, wenn eine Linie gefunden wurde.
                                            // Es wird keine Linie gefunden wenn alle Linien optimiert wurden, die mit dem
                                            // aktuellen Stift gezeichnet werden.

                    if (OptimierenAbbrechen)
                    {
                        break;
                    }

                    // ... suche eine Nachfolgerlinie.
                    foreach (HPGLElemente.Linie aktuelleLinie in _Linien)
                    {
                        // Wenn die Linie einen Stiftwechsel erfordern würde, ignoriere sie.
                        if (aktuelleLinie.Pen != AktuellerStift)
                        {
                            continue;
                        }

                        // Bereits optimierte Linien auch ignorieren.
                        if (aktuelleLinie.Optimiert)
                        {
                            // Ev. wäre es sinnvoll, die bereits optimierten aus der Liste zu entfernen, um die
                            // Geschwindigkeit zu erhöhen. Müssste man mal drüber nachdenken was das für Folgen hätte.
                            // --> Abbrechen nicht mehr möglich.
                            // --> Progress-Bar-Wert wird falsch berechnet.
                            continue;
                        }

                        // Berechne den Abstand zum aktuellen Kandidaten.
                        aktuellerAbstandV = (
                            (zuletztOptimierteLinie.EndX - aktuelleLinie.StartX) *
                            (zuletztOptimierteLinie.EndX - aktuelleLinie.StartX)
                            +
                            (zuletztOptimierteLinie.EndY - aktuelleLinie.StartY) *
                            (zuletztOptimierteLinie.EndY - aktuelleLinie.StartY)
                            );

                        // Berechne den Abstand zum Ende des aktuellen Kandidaten.
                        aktuellerAbstandR = (
                            (zuletztOptimierteLinie.EndX - aktuelleLinie.EndX) *
                            (zuletztOptimierteLinie.EndX - aktuelleLinie.EndX)
                            +
                            (zuletztOptimierteLinie.EndY - aktuelleLinie.EndY) *
                            (zuletztOptimierteLinie.EndY - aktuelleLinie.EndY)
                            );

                        if (aktuellerAbstandV < kleinsterAbstand)
                        {
                            kleinsterAbstand = aktuellerAbstandV;
                            besteLinie       = aktuelleLinie;
                            LinieRückwärts   = false;
                            LinieGefunden    = true;
                        }

                        if (aktuellerAbstandR < kleinsterAbstand)
                        {
                            kleinsterAbstand = aktuellerAbstandV;
                            besteLinie       = aktuelleLinie;
                            LinieRückwärts   = true;
                            LinieGefunden    = true;
                        }

                        // Wenn ich eine direkt anschließende Linie gefunden habe, kann ich die Suche stoppen.
                        if (aktuellerAbstandV == 0D)
                        {
                            break;
                        }
                    }

                    // Habe ich etwas gefunden, nimm es in die optimierte Liste auf.
                    if (LinieGefunden)
                    {
                        zuletztOptimierteLinie = besteLinie;

                        // Umdrehen, wenn das Ende näher war.
                        if (LinieRückwärts)
                        {
                            besteLinie.DreheUm();
                        }

                        besteLinie.Optimiert = true;

                        optimierteListe.Add(besteLinie);
                    }

                    if (optimierteListe.Count % 128 == 0)
                    {
                        if ((progressBar != null) && (label != null))
                        {
                            int Prozent = (int)(((float)optimierteListe.Count / (float)_Linien.Count) * 100F);
                            progressBar.Value = Prozent;
                            label.Text        = Prozent.ToString() + "%";
                            System.Windows.Forms.Application.DoEvents();
                        }
                    }
                }
            }

            if (!OptimierenAbbrechen)
            {
                _Linien = optimierteListe;
            }
        }