Laden...
G
Garzec myCSharp.de - Member
Gießen / Hessen Dabei seit 02.05.2016 50 Beiträge
Benutzerbeschreibung

Forenbeiträge von Garzec Ingesamt 50 Beiträge

10.01.2019 - 14:28 Uhr

Bei der Performance bin ich mir unsicher, ob ein permanentes Filtern eines großen Dictionaries schneller wäre, als ein Casten eines kleineren Dictionaries.

10.01.2019 - 13:17 Uhr

Du meinst du würdest einen großen Pool mit sämtlichen Komponenten halten und wenn du alle Positions Komponenten haben willst, danach filtern? Also alle Dictionary Values vom Typ Position?

10.01.2019 - 12:15 Uhr

@Abt

Ok, ich würde es dann casten. Aber könntest du deine anderen Sätze noch weiter erläutern? Wenn ich den generischen Typen nehme, habe ich die Möglichkeit genau vorzugeben, dass nur etwas rein darf, was das Interface implementiert und eben diesen angegebenen Typen auch wieder rauszubekommen.

Als Beispiel hier mal ein Pseudo Movement System, wie das Ganze dann hinterher abläuft

    internal class Movement : ISystem
    {
        public void Run()
        {
            for (int i = 0; i < EntityManager.ActiveEntities.Count; i++)
            {
                Guid entityId = EntityManager.ActiveEntities[i];

                if (EntityManager.GetComponentPool<Position>().TryGetValue(entityId, out Position positionComponent))
                {
                    if (EntityManager.GetComponentPool<MovementSpeed>().TryGetValue(entityId, out MovementSpeed movementSpeedComponent))
                    {
                        positionComponent.X += movementSpeedComponent.Value;
                        positionComponent.Y += movementSpeedComponent.Value;
                    }
                }
            }
        }
    }
10.01.2019 - 11:14 Uhr

Danke für deine Hilfe, deine genannten Fehler sind mir bereits aufgefallen, aber ich weiß nicht, ob ich einen Dictionary Cast erzwingen muss und ob dieser überhaupt so möglich ist. Ich ging davon aus, dass er bei where TComponent : IComponent weiß, dass dieses Element vom Typ des Interfaces ist.

Ich scheue mich aber ein wenig vor einem Cast, da dies wahrscheinlich etwas unperformant ist, von daher hat vielleicht noch jemand eine einfachere Idee? Damit meine ich einen ganz anderen Weg.

10.01.2019 - 10:08 Uhr

Also ich werde den EntityManager wahrscheinlich nicht statisch machen, weil statisch ist ja eigentlich böse ...

Aber ich dachte mir ich zeige einfach mal den Code, weil er sehr kurz ist, vielleicht verschafft das einen guten Überblick.

    internal interface IComponent
    {
    }

    internal interface ISystem
    {
        void Run();
    }

    internal static class EntityManager
    {
        private static List<Guid> activeEntities = new List<Guid>();

        public static IReadOnlyList<Guid> ActiveEntities { get { return activeEntities; } }

        private static KeyedByTypeCollection<Dictionary<Guid, IComponent>> componentPools = new KeyedByTypeCollection<Dictionary<Guid, IComponent>>();

        public static KeyedByTypeCollection<ISystem> Systems { get; } = new KeyedByTypeCollection<ISystem>();

        public static Guid CreateEntity()
        {
            Guid entityId = Guid.NewGuid();
            activeEntities.Add(entityId);
            return entityId;
        }

        public static void DestroyEntity(Guid entityId)
        {
            activeEntities.Remove(entityId);

            for (int i = 0; i < componentPools.Count; i++)
            {
                componentPools[i].Remove(entityId);
            }
        }

        public static Dictionary<Guid, TComponent> GetComponentPool<TComponent>() where TComponent : IComponent
        {
            return componentPools[typeof(TComponent)];
        }

        public static void AddComponentPool<TComponent>() where TComponent : IComponent
        {
            componentPools.Add(new Dictionary<Guid, TComponent>());
        }

        public static void RemoveComponentPool<TComponent>() where TComponent : IComponent
        {
            componentPools.Remove(typeof(TComponent));
        }

        public static void AddComponentToEntity(Guid entityId, IComponent component)
        {
            componentPools[component.GetType()].Add(entityId, component);
        }

        public static void RemoveComponentFromEntity<TComponent>(Guid entityId) where TComponent : IComponent
        {
            componentPools[typeof(TComponent)].Remove(entityId);
        }
    }

Momentan liegt es nur noch am oben genannten Problem. Aber ich hätte gerne eine Liste von Pools, die darauf achtet, dass jeder Pool einzigartig ist und die Pools selbst halten zur GUID (EntityID) die dazugehörige Komponente.

Durch die Dictionaries möchte ich einfach lange Suchen vermeiden.

10.01.2019 - 09:48 Uhr

@Thomas

Das habe ich leider schon probiert. Aber es ist ja auch logisch, wieso es nicht funktioniert. TComponent ist ja nur ein generischer Typparameter, den ich bei den Methoden definiert habe. Außerhalb der Methoden ist diese Variable natürlich nicht vorhanden.

10.01.2019 - 07:39 Uhr

Mit dem aktuellen Code erhalte ich aber 2 Fehler

GetComponentPool: Cannot implicitly convert IComponent to TComponent

AddComponentPool: Cannot convert from TComponent to IComponent

und da weiß ich nicht, wie ich das Ganze dann fixen muss.

09.01.2019 - 22:44 Uhr

Hallo,
ich versuche ein ganz minimalistisches Entity Component System aufzubauen. Ich könnte etwas fertiges nehmen, aber wollte es mal selbst versuchen. Zumal ich am Ziel bin, sobald diese Frage geklärt ist.

Ich erstelle ein Dictionary, das als Komponenten Pool dient. Dieser Pool hat als Key die ID der Entität (Entitäten sind bei mir nur GUIDs) und als Value die Komponente. Somit stellt jeder Pool einen einzelnen Komponententypen dar. Übergeordnet sollen die Pools in einer "Collection" liegen, damit man über diese Collection anhand des Komponententyps und der ID der Entität sehr schnell an die Komponente kommt, um Schleifen zu vermeiden.

Nun gibt es bereits die fertige Klasse KeyedByTypeCollection, die anscheinend darauf achten wird, dass jeder Pool in dieser Auflistung einzigartig bleibt.

Jede Komponente muss das Interface IComponent implementieren. Daher kann ich beim Hinzufügen, Suchen und Entfernen von Pools generische Typen erstellen, die das Interface erfordern.

        private KeyedByTypeCollection<Dictionary<Guid, IComponent>> componentPools = new KeyedByTypeCollection<Dictionary<Guid, IComponent>>();

        public Dictionary<Guid, TComponent> GetComponentPool<TComponent>() where TComponent : IComponent
        {
            return componentPools[typeof(TComponent)];
        }

        public void AddComponentPool<TComponent>() where TComponent : IComponent
        {
            componentPools.Add(new Dictionary<Guid, TComponent>());
        }

        public void RemoveComponentPool<TComponent>() where TComponent : IComponent
        {
            componentPools.Remove(typeof(TComponent));
        }

Nun ergibt sich das Problem, dass ich nicht

KeyedByTypeCollection<Dictionary<Guid, IComponent>>

schreiben kann, sondern eigentlich sowas haben müsste

KeyedByTypeCollection<Dictionary<Guid, Type where Type : IComponent>>

Hat jemand eine Idee, wie ich das Ganze fixen könnte?

08.11.2018 - 15:37 Uhr

Ich habe nun (wie beim Bild zu sehen) mal ein Control erstellt, das ein Label, einen Button und ein Kontext Menü beinhaltet.

 private class AllocationControl : UserControl
    {
        public AllocationControl(IndexField[] indexFields, BatchField[] batchFields)
        {
            Label lbl = new Label();
            Controls.Add(lbl);

            ContextMenuStrip contextMenu = new ContextMenuStrip();
            // das Menü befüllen ...
            Controls.Add(contextMenu);

            Button btn = new Button();
            btn.Click += (object sender, EventArgs e) =>
            {
                contextMenu.Show(Cursor.Position);
            };
            Controls.Add(btn);
        }

        public string DisplayedName { get; private set; }
        public double SelectedID { get; private set; }
    }

Dieses UserControl möchte ich dann einer selbstgeschriebenen Zelle übergeben

    private class DataGridViewAllocationCell : DataGridViewCell
    {
        public DataGridViewAllocationCell()
        {
        }

        protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
        {
            AllocationControl allocationControl = value as AllocationControl;
            Bitmap allocationControlImage = new Bitmap(cellBounds.Width, cellBounds.Height);
            allocationControl.DrawToBitmap(allocationControlImage, new Rectangle(0, 0, allocationControl.Width, allocationControl.Height));
            graphics.DrawImage(allocationControlImage, cellBounds.Location);
        }
    }

Und diese Zelle wird dann der selbstgeschriebenen Spalte hinzugefügt

    private class DataGridViewAllocationColumn : DataGridViewColumn
    {
        public DataGridViewAllocationColumn()
        {
            CellTemplate = new DataGridViewAllocationCell();
        }
    }

Bezüglich der DataGridViewAllocationCell werde ich aus dem Artikel

https://docs.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-host-controls-in-windows-forms-datagridview-cells

aber nicht so ganz schlau. Welche Eigenschaften sind zu überschreiben? Was für einen ValueType hat mein Control denn dann?

Hat jemand so etwas schon einmal gemacht und kann mir Hilfe bei den letzten Schritten Hilfestellung geben?

06.11.2018 - 08:46 Uhr

Bild 2 - Wie es aktuell ist

06.11.2018 - 08:43 Uhr

Bild 1 - Wie es sein soll

05.11.2018 - 16:21 Uhr

Hallo,
aktuell habe ich ein Datagridview Element mit 3 Spalten

<Externes Bild entfernt>

Die erste Spalte ist eine DataGridViewTextBoxColumn, die zweite und dritte Spalte sind vom Typ DataGridViewComboBoxColumn. Ich möchte eine Spalte erzeugen, die Dropdown Elemente pro Zeile hat. Dabei ist es möglich, dass die Kinder wieder eigene Dropdown Elemente sind. Leider fehlt mir der richtige Begriff für das Element, daher zeige ich hier ein Bild und hoffe, dass mir jemand sagen kann, nach was genau ich suchen muss. Ich befürchte aber, dass das eine selbst geschriebene GUI Komponente ist.

<Externes Bild entfernt>

Die Tabelle auf dem gezeigten Bild verbindet die Spalte 2 und 3. Bei einer Zeile klickt man rechts auf den Button und es öffnet sich ein Kontext Menü. Manche Items haben dabei Unterpunkte. Für meinen Anwendungsfall brauche ich nur 2 Einträge (BatchFields und IndexFields (beides Arrays)) mit X Subitems pro Array.

Hat jemand eine Idee, wie man sowas bauen kann?

Bei Bedarf kann ich auch meinen Code posten, mit dem ich das Grid auf dem ersten Bild erstellt habe, aber ich glaube aktuell ist es hierfür uninteressant.

Ich hoffe, dass ich nur Starthilfe brauche, aber leider kann ich nicht erkennen, wie die es umgesetzt haben, daher bin ich für jede Info dankbar 😃

02.11.2018 - 15:53 Uhr

Den Debugger habe ich benutzt, sonst hätte ich die anderen Infos ja nicht gewusst.

Aber "Alternativ lass einfach die Zuweisung zu ValueMember weg" hat funktioniert 😃

Danke

02.11.2018 - 15:19 Uhr

Also bei den ersten beiden Aufrufen hat cmbx.SelectedValue ein valides Objekt.

@Th69 null darf niemals vorkommen. Da ich nur aus einer Liste von Template Objekten wählen kann, muss ich immer ein valides Objekt selektiert haben und kann davon die ID auslesen.

@Abt eigentlich wie oben. Setze ich einen Haltepunkt bei der Property SelectedTemplateID so habe ich bei Aufruf 1 & 2 einen gültigen Wert und bei Aufruf 3 einen Nullpointer.

Aber bevor man versucht, auch bei Aufruf 3 einen gültigen Wert auszulesen ...

Warum wird das Event 3x ausgelöst? Das Beispielprojekt besteht nur aus diesem geposteten Code. Wenn ich über tabControl1_SelectedIndexChanged den Tab 2 auswähle, erwarte ich, dass die Combobox nur 1x gefüllt wird und er dadurch auch nur 1x comboBox1_SelectedValueChanged auslöst.

Jetzt, wo ich mich an @Th69 gehalten habe, erhalte ich ja schon einmal direkt beim ersten Aufruf den Nullpointer. Warum er aber nun sofort einen Nullpointer wirft und vorher erst 2x valide Werte liefert, ist mir ein Rätsel.

02.11.2018 - 11:44 Uhr

Danke für deine Antwort. Befolge ich deine Schritte, erhalte ich sofort einen Nullpointer. Das heißt es werden bei CreateTemplateSelection korrekte Template Objekte übergeben, frage ich aber bei SelectedTemplateID die ID des aktuell selektierten Templates ab, so ist cmbx.SelectedValue sofort null.

02.11.2018 - 10:09 Uhr

Ich habe ein TabControl Element mit mehreren Tabs. Auf dem zweiten Tab (Index 1) habe ich eine Combobox, die eine Template Auswahl verwaltet. Das Template Objekt selbst hat eine ID und einen Namen.

    internal class Template
    {
        public Template(double id, string name)
        {
            ID = id;
            Name = name;
        }

        public double ID { get; private set; }
        public string Name { get; private set; }
    }

Bei dieser Combobox möchte ich den Namen anzeigen, aber die ID auswählen können. Ich liefere hier mal einen fertigen Beispielcode zum ausprobieren.

Meine Form Klasse

    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            cmbx = new Cmbx(comboBox1); // Das Combobox Element übergeben
        }

        private Cmbx cmbx; // Die Klasse, die diese Combobox verwaltet

        private void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (tabControl1.SelectedIndex == 1) // Wurde Tab 2 ausgewählt?
            {
                cmbx.CreateTemplateSelection(myTemplates); // die Templates der Combobox übergeben
            }
        }

        private void comboBox1_SelectedValueChanged(object sender, EventArgs e)
        {
            // ausgewählte Template ID hier behandeln
            MessageBox.Show($"Combobox Change Event - Selected ID {cmbx.SelectedTemplateID}");
        }
    }

Meine Combobox Classe

    class Cmbx
        {
            public Cmbx(ComboBox cmbx)
            {
                this.cmbx = cmbx;
            }
    
            private ComboBox cmbx;
            private Template[] currentTemplates; // Die zuletzt zugewiesenen Templates
    
            public double SelectedTemplateID // Die aktuell ausgewählte ID abfragen
            {
                get
                {
                    Template templateInfo = cmbx.SelectedValue as Template;
                    return templateInfo.ID;
                }
            }
    
            public void CreateTemplateSelection(Template[] templates) // Die Combobox mit Daten füllen
            {
                if (currentTemplates != null) // Erster Durchlauf?
                {
                    if (currentTemplates.SequenceEqual(templates)) // Sind die neuen Daten anders?
                    {
                        return; // Abbrechen, wenn die Daten identisch sind
                    }
                }
    
                cmbx.DataSource = null; // Combobox leeren
                cmbx.Items.Clear();
    
                BindingSource bindingSource = new BindingSource();
                bindingSource.DataSource = templates;
                cmbx.DataSource = bindingSource.DataSource; // Die Daten der Combobox zuweisen
    
                cmbx.DisplayMember = nameof(Template.Name); // Den Template Namen anzeigen
                cmbx.ValueMember = nameof(Template.ID); // Die Template ID hinterlegen
    
                bool valid = templates.Length > 0; // Ist wenigstens 1 Datensatz vorhanden?
    
                if (valid && cmbx.SelectedIndex != 0)
                    cmbx.SelectedIndex = 0; // Den ersten Index auswählen
    
                currentTemplates = templates; // die neuen Templates merken
            }
        }

Wenn ich das Projekt starte und den zweiten Tab auswähle, wird das comboBox1_SelectedValueChanged 3x gefeuert.

Beim ersten und zweiten Aufruf erhalte ich von cmbx.SelectedTemplateID eine gültige ID.
Beim dritten Durchlauf erhalte ich einen Nullpointer.

Meine Frage ist:
Warum wird das Event 3x ausgelöst?
Und warum erhalte ich bei den ersten beiden Aufrufen gültige IDs und beim dritten Durchlauf einen Nullpointer?

18.10.2018 - 17:02 Uhr

Hallo,
Ich möchte eine DataGridViewComboBoxColumn befüllen. Die Combobox sollte das folgende struct repräsentieren.

internal struct IndexField
{
    public IndexField(int id, string name)
    {
        ID = id;
        Name = name;
    }

    public int ID { get; private set; }
    public string Name { get; private set; }
}

Meine bisherige Implementierung:

    public void Populate(IndexField[] indexFields)
    {
        DataGridViewComboBoxColumn indexFieldColumn = new DataGridViewComboBoxColumn()
        {
            HeaderText = "Index Fields"
        };

        indexFieldColumn.DataSource = indexFields;
        indexFieldColumn.DisplayMember = nameof(IndexField.Name);
        indexFieldColumn.ValueMember = nameof(IndexField.ID);

        dataGridView.Columns.Add(indexFieldColumn);

        for (int i = 0; i < 5; i++) // TESTZWECKE
        {
            dataGridView.Rows.Add(indexFields[0].Name); // erstes Item als Default Auswahl
        }
    }

Zur Laufzeit bekomme ich dann folgenden Fehler

Ich möchte also einen Text anzeigen, bei der Auswahl soll aber ein hinterlegter Wert genommen werden. Mit HTML würde das Ganze so aussehen:

<select>
  <option value="ID1">Item1</option>
  <option value="ID2">Item2</option>
  <option value="ID3">Item3</option>
</select>

Was mache ich falsch?

03.05.2017 - 09:30 Uhr

oh cool, vielen Dank 😃

03.05.2017 - 09:15 Uhr

Moment. Sorry. Ich kam vielleicht sehr unverständlich rüber.

Die Liste ist schon vorhanden, so wie du gesagt hast @panicJonny.

@LaTino das hatte ich falsch ausgedrückt. Ich habe ein Interface und diese abstrakte Klasse.

Dann versuche ich es nochmal zu beschreiben, ich habe die Basis

public abstract class CommonCell
{
// ist aktuell noch leer
}

dann habe ich noch das Interface

public Interface ICell
{
    void Methode1();
    void Methode2();
}

Und dann habe ich noch verschiedene Zellen.

public class Zelle1 : CommonCell, ICell
{
   public void Methode1()
{
// Tue dies
}

 public void Methode2()
{
// Tue jenes
}
}

public class Zelle2 : CommonCell, ICell
{
   public void Methode1()
{
// Tue dies
}

 public void Methode2()
{
// Tue jenes
}
}

Und diese Zellkinder liegen in einem Store. Dieser Store hält folgendes:


public class Store
{
    private List<Cell> cells = new List<Cell>(); // Wird gefüllt

    private void ActivateCells()
{
     foreach(Cell c in cells)
{
     c.Methode1();
     c.Methode2();
}
}
}

03.05.2017 - 08:52 Uhr

Hallo,
ich habe mich mal ins Thema Interfaces eingelesen.

Nun übe ich anhand von einem wirklich sehr simplen Spiel, es gibt 4 verschiedene "Zellen". Diese Zellen erben von einer Zellbasis.

public abstract class CommonCell{}

Jede Zelle enthält Informationen und implementiert durch das Interface Methoden.

Alle erzeugten Zellen werden in einer Liste gespeichert. In der Klasse, wo sich auch die Liste mit den Zellen befindet, möchte ich jede einzelne Zelle ansprechen und eine Methode aufrufen.

An die Methode müsste ich doch gelangen, da durch das Interface sichergestellt ist, dass diese Methode vorhanden ist. Ich weiß aber nicht so recht, wie ich die foreach-Schleife aufzubauen habe.


// Cells ist die Zell-Liste
foreach(Cell c in Cells)
{
      c.Methode();
}

Wie muss ich "Cell c" schreiben, das gibt es nicht, ich habe nur die abstrakte Basis und die Kinder Zelle1, Zelle2, Zelle3, Zelle4.

Also quasi eine allgemeine Referenz zu allen Zellen und darüber der Methodenaufruf..

Ich stehe da grade ein wenig auf dem Schlauch.

28.01.2017 - 18:52 Uhr

@Coder007 Ja weiß ich, aber aus privaten Gründen kenne ich das MVC Pattern schon ein wenig und wollte das auch in Unity nutzen. Habe mich eingelesen und gesehen das eigentlich beides möglich ist. Das MVC Pattern würde auch "Probleme" mit sich bringen, aber der Code wäre sehr strukturiert.

@Abt Tut mir Leid das hatte ich ganz vergessen! Also, ich habe eine Plattform und eine Falle. Beide bewegen sich von Punkt A zu Punkt B und wieder zurück, in Endlosschleife.

Dabei ist Punkt A das Objekt, dass den Start mit einem Trigger darstellt und Punkt B das Objekt, dass das Ende mit einem Trigger darstellt. Das "Mittelstück" ist das eigentliche wirkliche Objekt, also die Plattform oder die Falle an sich. Erreicht das Mittelstück den Trigger, so wird die Bewegungsrichtung geändert.

Und ich versuche Punkt A, Punkt B und das eigentliche Objekt an die Basisklasse zu übermitteln. Jeweils die Falle oder die Plattform oder zukünftige Dinge mit der gleichen Logik.

Also EndObject ist das gleiche wie MovingObject, sorry!

Hoffe das hilft 😃

28.01.2017 - 14:54 Uhr

Guten Tag,

ich versuche in Unity ein DesignPattern (MVC) umzusetzen. Da ich als Programmieranfänger noch viel Übung brauche, habe ich ein Problem bei der Weitergabe von Informationen.

Fallen und Plattformen nutzen bei mir die gleiche Logik, aus diesem Grund habe ich eine Basisklasse angelegt. Getrennt wird in "Data" (Daten) und "Controller" (Methoden).

In der Basisklasse habe ich folgendes Unity Objekt

public virtual GameObject MovingObject { get { return null; } }

Die erbende Unterklasse soll das Objekt "füllen", da ich ja nicht null haben will, sondern ein Objekt. Das mache ich so:

  [SerializeField]
    private GameObject movingObject;
    public override GameObject MovingObject { get { return movingObject; } }

Die private Variable wird im Editor gesetzt und gibt die Information an die Eigenschaft weiter und diese soll dann die Information überschreiben, sodass die Basisklasse das Objekt bekommt.

Leider bekomme ich NullExceptions, da die Objekte anscheinend in der Basisklasse nicht gesetzt werden, ist meine Logik falsch?

Zum Testen habe ich mal eine Prüfung eingebaut, in der Basisklasse:

private void Start()
    {
        if (!EndObject)
        {
            Debug.Log(EndObject+" IST NULL");
        }
    }

Und in der jeweiligen Unterklasse

private void Start()
    {
        if (EndObject)
        {
            Debug.Log(EndObject + " IST NICHT NULL");
        }
        else
        {
            Debug.Log(EndObject + " IST AUCH NULL");
        }
    }

Ich bekomme dann im Konsolenfester 2x ist null und 2x ist nicht null. In den Unterklassen sind die Informationen also vorhanden, sie werden nur nicht weitergegeben .. glaube ich ..

08.12.2016 - 20:51 Uhr

Die 2. Möglichkeit anstatt des Renderers wäre der Collider.

Aber da die Modelle ja aus Einzelteilen bestehen ist es schwierig dem leeren Gameobject als Container einen Collider zu geben

08.12.2016 - 17:05 Uhr

Ich weiß ja wie man den Debugger nutzt, ich weiß auch wie man ihn mit Unity nutzt.

Dennoch grübel ich über dem Thema, wieso manche Häuser noch ineinander hängen 😃

Selbst die genannte Codeänderung von t0ms3n lässt den Debugger nur 1x abbrechen, ich denke das sollte häufiger passieren.

08.12.2016 - 15:50 Uhr

Nachtrag:

Konnte den Code jetzt mal testen. Der Debugger kommt bei 100 Objekten ca. 1-2 mal an die Stelle, die den Code abbricht, weil sich Objekte schneiden.

Größere Häuser können dennoch gelegentlich ineinander spawnen :S

08.12.2016 - 09:41 Uhr

Habe grade leider noch keinen Zugriff aufs Projekt, habe aber schonmal eine Routine versucht:


private void SpawnObjects(GameObject planet, GameObject[] prefabs, float objectCount, float distanceToPlanet)
    {
            List<Bounds> objectsBoundsList = new List<Bounds>();
            for (int i = 0; i < objectCount; i++)
            {
                    GameObject spawnObject = prefabs[Random.Range(0, prefabs.Length)];
                    Vector3 spawnPos = calculator.CalcPointOnSphere(distanceToPlanet);
                    Bounds tempSpawnBounds = new Bounds(spawnPos, spawnObject.GetComponent<Renderer>().bounds.size);
                    foreach (Bounds objectBounds in objectsBoundsList)
                    {
                            if (objectBounds.Intersects(tempSpawnBounds))
                            {
                                    continue;
                            }
                    }
                    GameObject objectToSpawn = (GameObject)Instantiate(spawnObject, spawnPos, Quaternion.identity);
                    objectsBoundsList.Add(new Bounds(objectToSpawn.transform.position, objectToSpawn.GetComponent<Renderer>().bounds.size));
            }
    }

Testen kann ichs leider noch nicht...

07.12.2016 - 22:13 Uhr

Also da das Ganze "nur" ein Schulprojekt ist und ich das Ganze eher verstärkt dokumentieren muss, beschränke ich mich auf 100 Objekte. Einfach, damit mein alter Laptop das beim Vorstellen noch schafft.

Deine genannte Methode kannte ich noch gar nicht. Das klingt so, als wäre das Thema gar nicht so gigantisch wie gedacht 😄

Oder doch?

Bis jetzt hab ich erstmal meine alten Abi Bücher rauskramen müssen und viel Mathe auffrischen müssen 😛

07.12.2016 - 21:19 Uhr

Ich hatte gehofft das Ganze mathematisch zu lösen. Alle vorhandenen Objekte werden in einer Liste gespeichert, sodass nur noch prüfen muss, ob das Objekt an dem Platz keinen anderen "Würfel" schneidet, der dort schon platziert ist.

07.12.2016 - 15:24 Uhr

Hey,

durch die Schleife hängt sich das Projekt auf.

Also im Code

CalcCoordinates calculator;

    GameObject planet;
    public GameObject[] planetPrefabs;
    public GameObject[] skyPrefabs;
    public GameObject[] spacePrefabs;

    void Start()
    {
        calculator = GameObject.FindGameObjectWithTag("Calculator").GetComponent<CalcCoordinates>();

        planet = GameObject.FindGameObjectWithTag("Planet");

        SpawnObjects(planet, planetPrefabs, PlayerPrefs.GetInt("planetObjectsCount"), 50);
        SpawnObjects(planet, skyPrefabs, PlayerPrefs.GetInt("skyObjectsCount"), 150);
        SpawnObjects(planet, spacePrefabs, PlayerPrefs.GetInt("spaceObjectsCount"), 200);
    }

    private void SpawnObjects(GameObject planet, GameObject[] prefabs, float objectCount, float distanceToPlanet)
    {
        for (int i = 0; i < objectCount; i++)
        {
            Instantiate(prefabs[Random.Range(0, prefabs.Length)], calculator.CalcPointOnSphere(distanceToPlanet), Quaternion.identity);
        }
    }

hatte ich innerhalb der for-Schleife eingebaut:

Collider[] colliders = ...
do
{
Instantiate...
}
while
{
colliders != null;
}
06.12.2016 - 14:30 Uhr

Das weiß ich auch nicht, dadurch würde ich ja erstmal nur die Objekte geliefert bekommen.. Die habe ich ja aber bereits eigentlich

06.12.2016 - 13:18 Uhr

Hallo,
ich programmiere für ein Schulprojekt eine Simulation. Dabei hat man eine Kugel (Planet) und Objekte(Haus, Baum, ...), die zufällig platziert werden und dann per Gravitation angezogen werden.

Ich habe schon die Routine, die das Spawnen übernimmt. Fehlen tut mir eine Kollisionsprüfung, ob das neu zu spawnende Objekt am Punkt x,y,z mit der Größe "a,b,c" platziert werden darf, OHNE mit einem bereits vorhandenen Objekt zu kollidieren.

Weil ein Haus auf einem Baum wäre ja komisch.

Aus diesem Grund soll vor dem Spawnen eine Prüfung stattfinden, die Schwierigkeit liegt da einfach an der Kugel 😠

Ich habe den Mittelpunkt (setzen wir mal 0,0,0), den Radius, die Position des Objektes und die Größe des Objektes.

Ich habe bereits angefangen, komme allerdings bei der Kollisionsprüfung nicht mehr weiter:


public class WorldGenerator : MonoBehaviour
{
    CalcCoordinates calculator; // Hilfsklasse

    GameObject planet; // Der Planet
    public GameObject[] planetPrefabs; // Objekte auf dem Planeten
    public GameObject[] skyPrefabs; // Objekte in der Luft
    public GameObject[] spacePrefabs; // Objekte im All

    void Start()
    {
        calculator = GameObject.FindGameObjectWithTag("Calculator").GetComponent<CalcCoordinates>(); 
        planet = GameObject.FindGameObjectWithTag("Planet");

        SpawnObjects(planet, planetPrefabs, PlayerPrefs.GetInt("planetObjectsCount"), 50); // SpawnRoutine
        SpawnObjects(planet, skyPrefabs, PlayerPrefs.GetInt("skyObjectsCount"), 150);
        SpawnObjects(planet, spacePrefabs, PlayerPrefs.GetInt("spaceObjectsCount"), 200);
    }

    private void SpawnObjects(GameObject planet, GameObject[] prefabs, float objectCount, float distanceToPlanet)
    {
        List<gameObject> spawnObjectsList = new List<gameObject>(); // speichere alle bereits erstellten Objekte
        for (int i = 0; i < objectCount; i++)
        {
            gameObject spawnObject = prefabs[Random.Range(0, prefabs.Length)]; // Welches Objekt soll gespawnt werden?
            Vector3 spawnPos = calculator.CalcPointOnSphere(distanceToPlanet); // Wo soll das Objekt gespawnt werden?
            if(CheckSpawnPoint(spawnObjectsList, spawnObject, spawnPos)) // Kollisionsprüfung
            {
                    gameObject objectToSpawn = (gameObject)Instantiate(spawnObject, spawnPos, Quaternion.identity); // neues Objekt
                    spawnObjectsList.Add(objectToSpawn); // das neue Objekt der Liste hinzufügen
            }
        }
    }
    
    private bool CheckSpawnPoint(List<gameObject> spawnObjectsList, GameObject objectToSpawn, Vector3 spawnPos)
    {
        foreach(gameObject listObject in spawnObjectsList) // alle bereits gespawnten Objekte
        {
            if(..) // wenn das zu spawnende objekt mit einem bereits vorhandenen Objekt kollidieren würde ...
            {
                return false;
            }
        }
        return true;
    }
}

Ich hoffe die Kommentare helfen ein wenig, manche Unity-Begriffe besser zu verstehen.

Sonst einfach melden 🙂

19.07.2016 - 09:54 Uhr

Hi,
ich habe ein Tabcontrol, unter einem Reiter befindet sich ein Flashplayer. Gibt man einen falschen Link ein oder wechselt den Reiter, soll dieser pausiert werden oder gestoppt werden.

Dabei lassen die Aufrufe

axShockwaveFlash.Stop();
axShockwaveFlash.StopPlay();

den Player trotzdem einfach weiterspielen ..

Hat jemand eine Idee?

Edit: Ich habe die gleiche Frage auch unter

https://www.entwickler-ecke.de/viewtopic.php?p=701622#701622

gestellt.

14.06.2016 - 15:34 Uhr

Also nach einigem Testen funktioniert es glaube ich nur im Web oder mit grafischer Trickserei ... 😕

14.06.2016 - 10:28 Uhr

Also ich habe mal versucht das Ganze erstmal mit Strichen nachzubauen.


        private void btnQuellcode_Click(object sender, EventArgs e)
        {
            string markierterText = edtTextfeldEintraege.SelectedText;
            int linienCountFensterNormal = 87;
            int linienCountFensterMaximiert = 248;
            string strichKette = "";
            if (WindowState == FormWindowState.Normal)
            {
                for (int i = 0; i < linienCountFensterNormal; i++)
                {
                    strichKette += "-";
                }
            }
            else if (WindowState == FormWindowState.Maximized)
            {
                for (int i = 0; i < linienCountFensterMaximiert; i++)
                {
                    strichKette += "-";
                }
            }
            strichKette += Environment.NewLine;
            string neuerString = "\r\n\r\n" + markierterText.Insert(0,strichKette) + Environment.NewLine + strichKette + "\r\n\r\n";
            edtTextfeldEintraege.SelectedText = neuerString;
        }

Da die Striche aber langweilig aussehen fragte ich nach anderen Möglichkeiten 😛

14.06.2016 - 09:26 Uhr

Hi, danke für deine Antwort 😃

Ich bin mir nicht sicher ob es das ist, was ich suche. Mir geht es nicht um das Hervorheben von Syntax. Mir geht es nur um den "Container" der sich in der Richtextbox aufbauen soll. Den Code, den ich markiert habe, soll ich über einen Button dann in einen Container/ eine Box packen können, die sich dann vom geschriebenen Text abhebt.

13.06.2016 - 13:16 Uhr

Hi,

ich versuche in einem Projekt das optische Hervorheben von Code in einer Richtextbox nachzubauen. Deshalb wollte ich fragen, ob mir jemand sagen kann, ob es überhaupt möglich ist und wie es funktioniert, bzw. nach was man googlen kann.

Ich habe eine Richtextbox, schreibe meinen Text und kann über den Button dann den markierten Abschnitt in eine Box packen.


Wie hier ...

Danke 😃

09.05.2016 - 14:37 Uhr

Danke für deine Hinweise, das Thema Klassen zu erlernen, da bin ich grade dran, nebenbei wollte ich aber erst die Funktionalität des Programmes sicherstellen.

Ich nutze nun die "neue" Berechnung, und versuche die 5 Parameter bei Methodenaufruf zu übergeben. Leider kommt es da zu Fehlern. Der Code:


            for (int i = 0; i < punktListe.Count; i++)
            {
                for (int j = i + 2; j < 5; j++)
                {
                    PointF schnittpunkt = new PointF();
                    BerechneSchnittpunkt(punktListe[i], punktListe[j], punktListe[i + 1], punktListe[j +       1], out schnittpunkt);
                }
            }

Ich habe 2 Schleifen genommen, da er eine Exception bei einer Schleife wirft. Der Index übersteigt das Maximum und es geht nicht weiter. Dennoch kommen bei dieser Methode noch falsche Schnittpunkte heraus, meistens sind es sogar zu viele, ich denke er erkennt manche Eckpunkte noch als Schnittpunkte.

Meine Frage:

Stimmt meine neue Berechnung immer noch nicht oder übergebe ich die Parameter einfach nur falsch?

Ich habe zum Testen eine Schnittpunktliste erstellt, lasse ich die Schnittpunkte dazu malen, gehen die Linien kreuz und quer durch das Bild, die Berechnung muss also noch falsch sein ...

04.05.2016 - 15:17 Uhr

Also ich habe nun 2 Berechnungen, wobei ich weiß das die 2. Berechnung wohl das richtige Ergebnis liefert, die 1. Methode (meine Berechnung) noch nicht.

Meine Berechnung sieht momentan so aus:


private void SchnittpunktBerechnung(int startIndex1, int startIndex2)
        {
            // Punktindex

            int endeIndex1 = startIndex1 + 1;
            int endeIndex2 = startIndex2 + 1;

            Point start1 = punktListe[startIndex1];
            Point ende1 = punktListe[endeIndex1];
            Point start2 = punktListe[startIndex2];
            Point ende2 = punktListe[endeIndex2];

            // Zwischenwerte

            int x1 = ende1.X - start1.X;
            int x2 = start2.X - ende2.X;
            int x3 = start2.X - start1.X;

            int y1 = ende1.Y - start1.Y;
            int y2 = start2.Y - ende2.Y;
            int y3 = start2.Y - start1.Y;

            // Determinanten

            decimal d1 = x1 * y2 - y1 * x2;
            decimal d2 = x3 * y2 - y3 * x2;
            decimal d3 = x1 * y3 - y1 * x3;

            // s und t

            decimal s = d2 / d1;
            decimal t = d3 / d1;

            // Schnittpunktberechnung

            decimal schnittpunktX = start1.X + s * x1;
            decimal schnittpunktY = start1.Y + s * y1;

            // Überprüfung

            if (s >= 0 && t >= 0 && s <= 1 && t <= 1)
            {
                //Schnittpunkt auf der Strecke
            }
        }

Die neue Berechnung sieht wie folgt aus:


private void Tausche(float start, float ende)
        {
            float helper;
            helper = start;
            start = ende;
            ende = helper;
        }

        private bool LiegtDazwischen(float value, float start, float ende)
        {
            if (start > ende)
            {
                Tausche(start, ende);
            }
            return (start <= value) && (value <= ende);
        }

        private bool PunktLiegtDazwischen(PointF schnittpunkt, PointF punkt1, PointF punkt2)
        {
            return LiegtDazwischen(schnittpunkt.X, punkt1.X, punkt2.X) && LiegtDazwischen(schnittpunkt.Y, punkt1.Y, punkt2.Y);
        }

        private bool BerechneSchnittpunkt(PointF punkt1, PointF punkt2, PointF punkt3, PointF punkt4, PointF schnittpunkt)
        {
            float mx = punkt2.X - punkt1.X;
            float nx = punkt4.X - punkt3.X;
            float ox = punkt4.X * punkt3.Y - punkt3.X * punkt4.Y;

            float my = punkt2.Y - punkt1.Y;
            float ny = punkt4.Y - punkt3.Y;
            float oy = punkt2.X * punkt1.Y - punkt1.X * punkt2.Y;

            float d1 = mx * ny - my * nx;
            float d2 = nx * oy - mx * ox;
            float d3 = ny * oy - my * ox;

            if (d1 == 0)
            {
                //parallel
                schnittpunkt.X = 0;
                schnittpunkt.Y = 0;
                return false;
            }
            else
            {
                schnittpunkt.X = d2 / d1;
                schnittpunkt.Y = d3 / d1;
                return PunktLiegtDazwischen(schnittpunkt, punkt1, punkt2) && PunktLiegtDazwischen(schnittpunkt, punkt3, punkt4);
            }
        }

Aufgerufen wird meine Methode über eine Schleife, die dann über sämtliche Punkte geht:


  private void BerechneSchnittpunkte()
        {
            for (int i = 0; i < 5; i++)
            {
                for (int j = i + 2; j < 5; j++)
                {
                    SchnittpunktBerechnung(i, j);
                }
            }
        }

Würde es Sinn machen das Ganze hin zur 2. Berechnung umzubauen? Wenn ich versuche die 2. Berechnung mit 4 Methoden so abzuändern, dass diese Methode genauso wie meine Berechnung in der Schleife aufgerufen wird, dann komme ich als Anfänger sehr schnell mit den Parametern durcheinander, sodass es vorne und hinten nicht mehr stimmt.

Kann ich auch meine eigene Berechnung dahingehend abändern, dass die Methoden der 2. Berechnung greifen?

03.05.2016 - 12:54 Uhr

Hab 😃

Jetzt noch die Rechnung korrigieren 😛

03.05.2016 - 11:15 Uhr

Das ist immer unterschiedlich. Es wird ja abgeschnitten. Daher weichen die Punkte nicht so stark ab, aber er findet den Punkt ja dann nicht mehr auf der Strecke. Weil er ja nicht DIREKT drauf liegt, sondern ganz knapp daneben und dann findet er ihn nicht mehr. Daher erstmal meine Frage nach der Rechnung, ob diese richtig ist. Damit kann man dann ja weiterarbeiten.

03.05.2016 - 09:48 Uhr

Danke,

da ich mit double rechne wollte ich die Punkte, wie von LaTino schon vorgeschlagen, weglassen, um exakte Werte zu behalten. Nebenbei habe ich noch ein bisschen gekürzt und vereinfacht.

Das Ganze sieht nun so aus:



private void SchnittpunktBerechnung(int startIndex1, int startIndex2)
        {
            // Punktindex

            int endeIndex1 = startIndex1 + 1;
            int endeIndex2 = startIndex2 + 1;

            Point start1 = punktListe[startIndex1];
            Point ende1 = punktListe[endeIndex1];
            Point start2 = punktListe[startIndex2];
            Point ende2 = punktListe[endeIndex2];

            // Zwischenwerte

            int x1 = ende1.X - start1.X;
            int x2 = start2.X - ende2.X; 
            int x3 = start2.X - start1.X; 

            int y1 = ende1.Y - start1.Y; 
            int y2 = start2.Y - ende2.Y;   
            int y3 = start2.Y - start1.Y;  

            // Determinanten

            int d1 = x1 * y2 - y1 * x2; 
            int d2 = x3 * y2 - y3 * x2;    
            int d3 = x1 * y3 - y1 * x3;   

            // s und t

            double s = d2 / d1;
            double t = d3 / d1;

            // Schnittpunktberechnung

            double schnittpunktX = start1.X + s * x1;
            double schnittpunktY = start1.Y + t * y1;

            // Überprüfung

            if (s >= 0 && t <= 1)
            {
                                   //Schnittpunkt auf der Strecke
            }
        }


Dennoch kommen beim Testen nicht die gewünschten Ergebnisse raus, also Er findet nicht den exakten Schnittpunkt auf der Strecke.

Kann mir jemand sagen ob bei der Rechnung oben noch Fehler eingebaut sind? Das mathematische hier ins Programm umzuschreiben fand ich doch nicht so einfach wie gedacht 😁

02.05.2016 - 15:51 Uhr

Ich habe dich schon verstanden. Meine letzte Frage zielte darauf ab, ob es dann eine Möglichkeit gibt das ganze dann anders zu lösen. Wenn ich den Schnittpunkt in 2 float Werte aufteile müsste ich damit ja weiterrechnen und diese Werte dann mit der Geraden abgleichen.

02.05.2016 - 15:30 Uhr

Sorry dein Edit kam erst nach meiner Antwort 😃 bzw. hatte die Seite noch nicht neu geladen

Edit: Du hast Recht, das Runden führt zu Fehlern. Aber eigentlich habe ich dann nur vor dem


Point schnittPunkt = new Point(sx, sy);

exakte Werte zu übergeben. Und da muss ichs ja irgendwie hinbekommen, dass sx und sy von Kommazahlen zu Integern übergehen =?

02.05.2016 - 14:58 Uhr

Damit meinte ich die Parameter die man mitgeben kann,



            // Schnittpunktberechnung

            int sx = Round(start1.X + s * x1);
            int sy = Round(start1.Y + s * y1);

            // Schnittpunkt

            Point schnittPunkt = new Point(sx, sy);


sx und sy müssen integer sein, bei double etc. meckert er

02.05.2016 - 14:28 Uhr

Tut mir leid ich bin ein Programmieranfänger.

Der Punkt kann nur Int-Werte annehmen, wie könnte ich das Ganze umbauen das er die richtigen Werte entgegen nimmt?

Ich versuche ja schon erst am Ende zu runden.

02.05.2016 - 14:24 Uhr

Sorry, meine Rundungsmethode:


private int Round(double d)
        {
            if (double.IsPositiveInfinity(d))
                return int.MaxValue;
            if (double.IsNegativeInfinity(d))
                return int.MinValue;
            return Convert.ToInt32(Math.Round(d, MidpointRounding.AwayFromZero));
        }

02.05.2016 - 13:53 Uhr

Ich habe meine Berechnung abgeändert, s wird jetzt auch nicht mehr 0. mx,nx,ox, .... dienen eigentlich nur als Zwischenschritte. Ich könnte unten in die Rechnung ja auch direkt die variablen eingeben, aber dann würde es denke ich zu unübersichtlich und die Berechnung zu groß/lang.

Das Ganze sieht nun so aus:



            int x1 = start1.X;      //Punkt1 X
            int x2 = ende1.X;       //Punkt2 X
            int x3 = start2.X;      //Punkt3 X
            int x4 = ende2.X;       //Punkt4 X

            int y1 = start1.Y;      //Punkt1 Y
            int y2 = ende1.Y;       //Punkt2 Y
            int y3 = start2.Y;      //Punkt3 Y
            int y4 = ende2.Y;       //Punkt4 Y

            // Konstanten

            int mx = x2 - x1;
            int nx = x4 - x3;
            int ox = x3 - x1;

            int my = y2 - y1;
            int ny = y4 - y3;
            int oy = y3 - y1;

            // Determinanten

            int d1 = mx * ny - my * nx;
            int d2 = ox * ny - oy * nx;
            int d3 = mx * oy - my * ox;

            // s und t

            double s = 1F * d2 / d1;
            double t = 1F * d3 / d1;

            // Schnittpunktberechnung

            int sx = Round(x1 + s * (x2 - x1));
            int sy = Round(y1 + s * (y2 - y1));


Dennoch erkennt er die Schnittpunkte nicht richtig. Mache ich noch etwas falsch?

02.05.2016 - 13:20 Uhr

Achso sorry, ich hatte unten noch geschrieben, dass die Kommentare rechts einfach nur meine ursprüngliche "Berechnung" war. Also das, was vorher da stand.

Den Debugger hatte ich schon benutzt, daher weiß ich ja das s immer 0 ist und t immer 1. Führe ich das ganze zurück sind oben die Startberechnungen falsch.

Du hast Recht, dass ich das am Besten selber rausfinden kann, trotzdem dachte ich vielleicht erkennt jemand oben schon den Fehler.

02.05.2016 - 13:07 Uhr

Das es sich bei nx und ox doppelt ist vom Abschreiben richtig, falls du das meinst.

Deswegen ja meine Frage nach dem Fehler in der Berechnung 😕

02.05.2016 - 10:40 Uhr

Hallo 🙂

ich versuche den Schnittpunkt von zwei Geraden zu berechnen. Benötigen tue ich das für eine Berechnung einer Fläche eines zufällig generierten Polygons. Mir geht es hierbei aber erstmal nur um die Schnittpunktberechnung. Momentan sieht diese so aus:



private void SchnittpunktBerechnung(int startIndex1, int startIndex2)
        {
            //Strecke AB = Punkt1 + s * (Punkt2 - Punkt1)
            //Strecke CD = Punkt3 + t * (Punkt4 - Punkt3)

            int endeIndex1 = startIndex1 + 1;
            int endeIndex2 = startIndex2 + 1;

            Point start1 = punktListe[startIndex1];
            Point ende1 = punktListe[endeIndex1];
            Point start2 = punktListe[startIndex2];
            Point ende2 = punktListe[endeIndex2];

            // Streckenfarben

            Color farbe1 = farbenListe[startIndex1];
            Color farbe2 = farbenListe[startIndex2];

            // Punkte

            int x1 = start1.X;      //Punkt1 X
            int x2 = ende1.X;       //Punkt2 X
            int x3 = start2.X;      //Punkt3 X
            int x4 = ende2.X;       //Punkt4 X

            int y1 = start1.Y;      //Punkt1 Y
            int y2 = ende1.Y;       //Punkt2 Y
            int y3 = start2.Y;      //Punkt3 Y
            int y4 = ende2.Y;       //Punkt4 Y

            // Konstanten

            int mx = x2 - x1;
            int nx = x3 - x4;  //x4 - x3;
            int ox = x3 - x4;  //x3 - x1;

            int my = y2 - y1;
            int ny = y3 - y4;  //y4 - y3;
            int oy = y3 - y4;  //y3 - y1;

            // Determinanten

            int d1 = mx * ny - my * nx;
            int d2 = ox * ny - oy * nx;
            int d3 = mx * oy - my * ox;

            // Fallunterscheidung

            if (d1 == d2 && d1 == d3 && d1 == 0)
            {
                Console.WriteLine("Strecken liegen aufeinander");    //------- TEST
            }
            else if (d1 == 0 && d2 != 0 && d3 != 0)
            {
                Console.WriteLine("kein Schnittpunkt");    //------- TEST
            }
            else if (d1 != 0)
            {
                Console.WriteLine("Schnittpunkt");    //------- TEST
            }

            // s und t

            double s = 1F * d2 / d1;
            double t = 1F * d3 / d1;

            // Überprüfung s und t

            Console.WriteLine("Strecke: " + farbe1 + "Strecke: " + farbe2);    //------- TEST

            if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
            {
                Console.WriteLine("Schnittpunkt auf den Strecken");    //------- TEST
            }
            else
            {
                Console.WriteLine("Schnittpunkt auf den Geraden aber nicht auf den Strecken");    //------- TEST
            }

            // Schnittpunktberechnung

            int sx = Round(x1 + s * (x2 - x1));
            int sy = Round(y1 + s * (y2 - y1));

            // Schnittpunkt

            Point schnittPunkt = new Point(sx, sy);

            Console.WriteLine(schnittPunkt);    //------- TEST

            Console.WriteLine("s: " + s + " t: " + t);

            Console.WriteLine("************************************************************");    //------- TEST
        }


Das Problem an der Sache ist, das bei meiner Testroutine immer s=0 und t=1 ist. Und das Problem liegt wohl oben bei den Konstanten. Rechts auskommentiert habe ich meine vorherige Berechnung, diese stimmte aber auch nicht ganz. Kennt ein Mathe-Ass die richtige Rechnung? 😜