Witam,
MIMO IŻ TO DŁUGI POST TO PROSZĘ O ZAINTERESOWANIE SIĘ NIM!
Piszę program w którym będzie można pisać wzory matematyczne. Problem mam z napisaniem struktury. Przyznam, że już długo nad tym siedzę, już rysowałem wzory, ale ciągle jest problem z rozmieszczeniem elementów matematycznych w przypadku złożonych wzorów.
Struktura przechowująca wzór to drzewo, ale nie binarne. Każdy element (prócz korzenia) posiada wskaźnik "Parent" który wskazuje na rodzica i każdy element posiada obiekt Child typu std::vector przechowujący wskaźniki na elementy potomne (jeżeli takie są).
W super uproszczeniu podaje jak mniej więcej wyglądają 2 klasy.
expression.h
class Expression
{
public:
Expression();
~Expression();
//dodaje element do struktury (wstawia go na koncu
virtual Expression* Add(Expression*) = 0;
//dodaje element potomny
virtual Expression* AddChild(Expression*) = 0;
Expression* Head; //pierwszy element
Expression* Parent; //rodzic
std::vector<Expression*> Child; //dzieci
//pokazuje elementy od podanego w parametrze
//jezeli podamy w nim Head to odrysuje wszytko
//jest to rekurencyjne wywolanie metody Show()
void Show(Expression*);
protected:
//odrydowuje element danego typu
virtual void Show() = 0;
//metoda przesuwa wszystkie elementy potomne
//1 paremetr: ile w lewo
//2 parametr: ile w gore
virtual void Move(Expression*,const int, const int);
};
subscript.h
class Subscript : public Expression
{
public:
Expression();
~Expression();
virtual Expression* Add(Expression*);
virtual Expression* AddChild(Expression*);
Expression* Head;
Expression* Parent;
std::vector<Expression*> Child;
void Show(Expression*);
protected:
virtual void Show();
virtual void Move(Expression*,const int, const int);
};
Nagłówki klas które napisałem to oczywiście chyba największe uproszczenie tego co mam, ale chodzi o coś innego. Czy taka koncepcja jest dobra.
Wywołanie wyglądałby tak:
//to w jakims konstruktorze
//expression to skladowa prywatna jakies klasy programu
expression = new Begin;
//Begin to taka klasa, ktorej obiekt moze wystapic tylko raz
//jest pierwszym elementem kazdego wzoru matematycznego
//klikniecie na jakis przycisk
Identifier* id = new Identifier; //reprezentuje identyfikator
id->Ascii(242);
id->Font->Name("Math1");
//znak 242 w czcionce Math1 to znak calki
expression = expression->Add(id);
I TERAZ:
Opisałem jak podkreślam mniej więcej to wyglądam ze zdecydowanie na mniej, ale rzecz w tym że mam problem z rozmieszczeniem poszczególnych elementów.
Kiedy umieszczam pierwszy element (np. podaną wyżej całkę) sprawdzany jest jej rozmiar. Ponieważ jest pierwszym elementem umieszczany jest w punkcie 0,0. Następny element jest umieszczany w punkcie:
Poprzedni->Left + Poprzedni->Szerokosc
Jeżeli dodawany element jest wyższy od poprzedniego to poprzedni jest odbiżany metodą Move;
Metoda ta nie sprawdza się dla zagnieżdżonych elementów.
Dlaczego?
Dodawane elementy są dodawane do pierwszego elementu zwanego rodzicem i zarazem korzeniem. Dodaje coś do niego i mogę zmienić to w rodzicu czyli jednocześnie w korzeniu.
Przy bardziej zagłębionych elementach musiałbym się odwoływać do rodzica rodzica rodzica... aż do korzenia. Teoretycznie wydaje się to proste, ale przy implementowaniu metody Add() w klasie Subscript (indek dolny) może to już być zagmatwane. Trzeba tak napisać żeby każdy potomek zmieniał wielkość rodzica. O ile? Zaczynają się schody.
WIEM ŻE NAPISAŁEM DUŻO I BYĆ MOŻE NIEZROZUMIALE ALE NIE WIEM JAK OPISAĆ TO PROŚCIE!
Chodzi mi o to abyście mi podpowiedzieli jakiś schemat do obliczania położenia poszczególnych elementów.
Z góry dzieki za pomoc.
Jeśli w ogóle ktoś to doczytał:-)