32 #pragma region Constructors and destructors 58 const UINT bShowRules =
m_bShowRules? MF_CHECKED: MF_UNCHECKED;
80 #pragma endregion Constructors and destructors 85 #pragma region Drawing functions 92 HDC hdc = BeginPaint(
m_hWnd, &ps);
93 Gdiplus::Graphics graphics(hdc);
103 GetClientRect(
m_hWnd, &rectClient);
104 const int nClientWidth = rectClient.right - rectClient.left;
105 const int nClientHt = rectClient.bottom - rectClient.top;
111 const int margin = 10;
113 const float xscale = float(nClientWidth
114 - (textwidth > 0? 3: 2)*margin - textwidth)/w;
115 const float yscale = float(nClientHt - 2*margin)/h;
116 const float scale = min(min(xscale, yscale), 1);
118 Gdiplus::Rect rectDest;
120 rectDest.Width = (int)std::floor(scale*w);
121 rectDest.Height = (int)std::floor(scale*h);
123 rectDest.X = max(2*margin + textwidth,
124 (nClientWidth - rectDest.Width + textwidth)/2);
125 rectDest.Y = max(margin, (nClientHt - rectDest.Height)/2);
132 DrawRules(graphics, Gdiplus::PointF(margin, margin));
142 Gdiplus::SolidBrush brush(Gdiplus::Color::DarkCyan);
147 graphics.DrawString(temp.c_str(), -1,
m_pFont, p, &brush);
160 std::stack<StackFrame> stack;
164 Gdiplus::Graphics* pGraphics =
nullptr;
166 Gdiplus::PointF ptCur;
170 Gdiplus::Pen pen(Gdiplus::Color::Black);
177 r.left = int(std::floor(ptCur.X));
178 r.right = int(std::ceil (ptCur.X));
179 r.top = int(std::floor(ptCur.Y));
180 r.bottom = int(std::ceil (ptCur.Y));
185 for(
size_t j=0; j<s.size(); j++){
186 Gdiplus::PointF ptNext;
192 ptNext = ptCur - Gdiplus::PointF(-len*sinf(angle), len*cosf(angle));
195 else pGraphics->DrawLine(&pen, ptCur, ptNext);
232 const int w = r.right - r.left;
233 const int h = r.bottom - r.top;
234 m_pBitmap =
new Gdiplus::Bitmap(w, h, PixelFormat32bppARGB);
235 ptCur = Gdiplus::PointF(-(
float)r.left, -(
float)r.top);
239 pGraphics =
new Gdiplus::Graphics(
m_pBitmap);
240 pGraphics->SetSmoothingMode(Gdiplus::SmoothingModeHighQuality);
241 pGraphics->Clear(Gdiplus::Color::Transparent);
272 InvalidateRect(
m_hWnd,
nullptr, TRUE);
275 #pragma endregion Drawing functions 280 #pragma region Menu functions 286 HMENU hMenubar = CreateMenu();
295 AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)
m_hFileMenu, L
"&File");
302 L
"Plant-like (Fig. 1.24a)");
304 L
"Plant-like (Fig. 1.24b)");
306 L
"Plant-like (Fig. 1.24c)");
308 L
"Plant-like (Fig. 1.24d)");
310 L
"Plant-like (Fig. 1.24e)");
312 L
"Plant-like (Fig. 1.24f)");
314 AppendMenuW(
m_hLSMenu, MF_SEPARATOR, 0,
nullptr);
317 L
"Stochastic branching (Fig. 1.27)");
319 L
"Hexagonal Gosper curve (Fig. 1.11a)");
321 AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)
m_hLSMenu, L
"&L-System");
330 AppendMenuW(hMenubar, MF_POPUP, (UINT_PTR)
m_hViewMenu, L
"&View");
334 SetMenu(
m_hWnd, hMenubar);
343 CheckMenuItem(
m_hLSMenu, i, MF_UNCHECKED);
353 EnableMenuItem(
m_hFileMenu, 0, MF_ENABLED | MF_BYPOSITION);
354 else EnableMenuItem(
m_hFileMenu, 0, MF_GRAYED | MF_BYPOSITION);
357 #pragma endregion Menu functions 362 #pragma region Settings functions 455 const UINT status =
m_bShowRules? MF_CHECKED: MF_UNCHECKED;
457 InvalidateRect(
m_hWnd,
nullptr, TRUE);
460 #pragma endregion Settings functions 468 int nNumGenerations = 0;
513 const Gdiplus::CharacterRange charRange(0, (
int)strRules.size());
514 Gdiplus::StringFormat sf;
515 sf.SetMeasurableCharacterRanges(1, &charRange);
517 const int n = sf.GetMeasurableCharacterRangeCount();
518 Gdiplus::Region* rg =
new Gdiplus::Region[n];
519 graphics.MeasureCharacterRanges(strRules.c_str(), -1,
m_pFont, r, &sf, n, rg);
525 for(
int i=0; i<n; i++){
527 rg[i].GetBounds(&r, &graphics);
528 width = max(width, r.Width);
void SetLSystemMenuChecks()
Set L-system menu checkmarks.
UINT m_nType
Current L-system type.
ULONG_PTR m_gdiplusToken
GDI+ token.
float m_fPointSize
Line point size.
Turtle graphics descriptor.
float m_fAngleDelta
Line angle delta in radians.
#define IDM_LSYS_PLANT_D
Menu id for Fig. 1.24d.
int GetRuleStrWidth(Gdiplus::Graphics &graphics)
Get rule string width.
Gdiplus::Font * m_pFont
Font.
float m_fAngle
Rotation angle.
void Clear()
Clear the rules, buffers, and settings.
Gdiplus::Bitmap * m_pBitmap
Pointer to a bitmap image.
#define IDM_VIEW_THICKLINES
Menu id for thick lines.
#define IDM_LSYS_PLANT_B
Menu id for Fig. 1.24b.
void CreateMenus()
Create menus.
Gdiplus::Bitmap * GetBitmap()
Get pointer to bitmap.
const bool IsStochastic() const
Is a stochastic L-system.
#define IDM_LSYS_BRANCHING
Menu id for branching structure.
#define IDM_FILE_QUIT
Menu id for Quit.
void AddPointToRect(RECT &r, Gdiplus::PointF point)
Add point to rectangle.
Interface for some helpful Windows-specific functions.
void EnableGenerateMenuEntry()
Enable Generate in File menu.
#define IDM_FILE_SAVE
Menu id for Save.
Stochastic context-free production.
void Generate()
Generate L-system string.
void ToggleShowRules()
Toggle the show rules flag.
#define IDM_LSYS_PLANT_C
Menu id for Fig. 1.24c.
const std::wstring & GetRuleString() const
Get rule string.
HMENU m_hViewMenu
Handle to the View menu.
Interface for the main class CMain.
CMain(const HWND hwnd)
Constructor.
const bool IsStochastic() const
Is a stochastic L-system.
void SetRules()
Create the L-system rules.
LSystem m_cLSystem
The L-system.
#define IDM_FILE_GENERATE
Menu id for Save.
HMENU m_hFileMenu
Handle to the File menu.
#define IDM_LSYS_PLANT_E
Menu id for Fig. 1.24e.
#define IDM_LSYS_HEXGOSPER
Menu id for hexagonal Gosper curve.
const std::wstring & GetString() const
Get generated string.
const UINT GetGenerations() const
Get number of generations.
void AddRule(const LProduction &rule)
AddRule rule.
bool m_bShowRules
Whether to show the rules.
bool m_bThickLines
Line thickness flag.
HMENU m_hLSMenu
Handle to the L-System menu.
void Generate(const UINT n)
Generate L-system from stored root and rules.
#define IDM_LSYS_PLANT_A
Menu id for Fig. 1.24a.
void ToggleLineThickness()
Toggle the line thickness flag.
float m_fLenMultiplier
Line length multiplier.
#define IDM_VIEW_RULES
Menu id for showing rules.
ULONG_PTR InitGDIPlus()
Initialize GDI+.
void OnPaint()
Paint the client area.
#define IDM_LSYS_PLANT_F
Menu id for Fig. 1.24f.
Gdiplus::PointF m_ptPos
Position.
void SetRoot(const std::wstring &omega)
Set the root string.
void DrawRules(Gdiplus::Graphics &graphics, Gdiplus::PointF p)
Draw rules.
Gdiplus::FontFamily * m_pFontFamily
Font family.
void SetType(UINT t)
Set type.
void Draw()
Draw turtle graphics.
HWND m_hWnd
Window handle.
float m_fLength
Line length.
Gdiplus::RectF GetClientRectF(HWND hwnd)
Get client rectangle as a RectF.