OSDN Git Service

Initial Commit
[qcad/qcad.git] / qcadwin / QDrawGraph.cpp
1 //---------------------------------------------------------------------------\r
2 // Show qubits' states\r
3 //---------------------------------------------------------------------------\r
4 #include <vcl.h>\r
5 #pragma hdrstop\r
6 \r
7 //using namespace std;\r
8 \r
9 #include <new>\r
10 #include <cmath>\r
11 #include <cstdio>\r
12 #include <cstdlib>\r
13 #include <algorithm>\r
14 #include <sstream>\r
15 #include <iomanip>\r
16 #include "QDrawGraph.h"\r
17 //---------------------------------------------------------------------------\r
18 #pragma package(smart_init)\r
19 //---------------------------------------------------------------------------\r
20 const double QDrawGraph::EPS = 1.0e-10; // Cut-off for showing non-zero\r
21 //---------------------------------------------------------------------------\r
22 /**\r
23  *  Constructor\r
24  */\r
25 QDrawGraph::QDrawGraph(TCanvas *_Canvas) {\r
26   mCanvas = _Canvas;\r
27   mViewingTop = 0;\r
28 \r
29   mDrawMode = DM_ALL;\r
30   mTopWindowMargin = 30;\r
31   mTopMargin    = 10;\r
32   mBottomMargin = 10;\r
33   mLeftMargin   = 10;\r
34   mRightMargin  = 10;\r
35   mRowMargin    = 10;\r
36   mIAMargin     = 20;\r
37   mAVMargin     = 20;\r
38   mVQMargin     = 20;\r
39   mStrOffset    = 10;\r
40   SetPrecision(5);\r
41   SetFontSizeOfQbit(14);\r
42   SetFontSizeOfValue(14);\r
43   SetSizeOfArrow(40);\r
44 }\r
45 //---------------------------------------------------------------------------\r
46 /**\r
47  *  Destructor\r
48  */\r
49 QDrawGraph::~QDrawGraph() {\r
50 }\r
51 //---------------------------------------------------------------------------\r
52 /**\r
53  *  Draw all states\r
54  */\r
55 void\r
56 QDrawGraph::DrawAll(const QBits *qbits, const int type) {\r
57 \r
58   mCanvas->Brush->Color = clWhite;\r
59   mCanvas->FillRect(Rect(0,0,mImageWidth,mImageHeight));\r
60   SetSize(qbits);\r
61   int num_state = qbits->GetNumberOfStates();\r
62   for (int i = 0; i < num_state; i++) {\r
63     DrawNthRow(qbits, i, i);\r
64   }\r
65 }\r
66 //---------------------------------------------------------------------------\r
67 /**\r
68  *  Draw Only NonZero States\r
69  */\r
70 void\r
71 QDrawGraph::DrawNonZero(const QBits *qbits) {\r
72   mCanvas->Brush->Color = clWhite;\r
73   mCanvas->FillRect(Rect(0,0,mImageWidth,mImageHeight));\r
74 \r
75   std::vector<int> vq;\r
76   for (int i=0;i<qbits->GetNumberOfStates();i++) {\r
77     double re = qbits->NthStateR(i);\r
78     double im = qbits->NthStateI(i);\r
79     if (re*re+im*im > EPS) {\r
80       vq.push_back(i);\r
81     }\r
82   }\r
83   for (int i=0;i<(int)vq.size();i++) {\r
84     DrawNthRow(qbits,vq[i],i);\r
85   }\r
86 }\r
87 //---------------------------------------------------------------------------\r
88 /**\r
89  *\r
90  */\r
91 void\r
92 QDrawGraph::Paint(const QBits *qbits) {\r
93   switch (GetDrawMode()) {\r
94   case DM_ALL:\r
95     DrawAll(qbits);\r
96     break;\r
97   case DM_NONZERO:\r
98     DrawNonZero(qbits);\r
99     break;\r
100   }\r
101 }\r
102 //---------------------------------------------------------------------------\r
103 void\r
104 QDrawGraph::SetDrawMode(int Mode,const QBits *qbits) {\r
105   mDrawMode = Mode;\r
106   SetSize(qbits);\r
107   SetViewingTop(0);\r
108   switch (GetDrawMode()) {\r
109   case DM_ALL:\r
110     SetSize(qbits);\r
111     break;\r
112   case DM_NONZERO:\r
113     SetSizeNonZero(qbits);\r
114     break;\r
115   }\r
116 }\r
117 //---------------------------------------------------------------------------\r
118 void\r
119 QDrawGraph::SetSize(const QBits *qbits) {\r
120 \r
121   int num_state = qbits->GetNumberOfStates();\r
122   SetPageFormat(qbits);\r
123 \r
124   mWidth = mLeftMargin + mWidthOfIndex + mIAMargin + mWidthOfArrow + mAVMargin\r
125            + mWidthOfValue + mVQMargin + mWidthOfQbits + mRightMargin;\r
126   mHeight = mTopMargin + num_state * (mRowMargin + GetRowHeight())\r
127             + mBottomMargin + mTopMargin + mTopWindowMargin;\r
128 \r
129   if (mHeight < mImageHeight)mHeight = mImageHeight;\r
130 }\r
131 //---------------------------------------------------------------------------\r
132 void\r
133 QDrawGraph::SetViewingTop(int t) {\r
134   if (t<0) {\r
135     t=0;\r
136   } else if (t > (mHeight- mImageHeight)) {\r
137     t = (mHeight- mImageHeight);\r
138   }\r
139   mViewingTop = t;\r
140 }\r
141 //---------------------------------------------------------------------------\r
142 /**\r
143  * Get size to show only non-zero states\r
144  */\r
145 void\r
146 QDrawGraph::SetSizeNonZero(const QBits *qbits) {\r
147 \r
148   int num_state = GetNonZeroCount(qbits);\r
149   SetPageFormat(qbits);\r
150 \r
151   mWidth = mLeftMargin + mWidthOfIndex + mIAMargin + mWidthOfArrow + mAVMargin\r
152            + mWidthOfValue + mVQMargin + mWidthOfQbits + mRightMargin;\r
153   mHeight = mTopMargin + num_state * (mRowMargin + GetRowHeight())\r
154             + mBottomMargin + mTopMargin + mTopWindowMargin;\r
155 \r
156   if (mHeight < mImageHeight)mHeight = mImageHeight;\r
157 }\r
158 \r
159 //---------------------------------------------------------------------------\r
160 // Utility functions\r
161 //---------------------------------------------------------------------------\r
162 \r
163 //---------------------------------------------------------------------------\r
164 int\r
165 QDrawGraph::GetRowHeight(void) const {\r
166   int max_height;\r
167   max_height = mHeightOfArrow >= mHeightOfValue ? mHeightOfArrow : mHeightOfValue;\r
168   max_height = max_height >= mHeightOfQbits ? max_height : mHeightOfQbits;\r
169   max_height = max_height >= mHeightOfIndex ? max_height : mHeightOfIndex;\r
170   return max_height;\r
171 }\r
172 //---------------------------------------------------------------------------\r
173 /**\r
174  *\r
175  */\r
176 void\r
177 QDrawGraph::SetPageFormat(const QBits *qbits) {\r
178   const double LOG10 = 2.3025850929940456840179914546844;\r
179   int num_state = qbits->GetNumberOfStates();\r
180   int num_qbits = qbits->GetNumberOfQBits();\r
181 \r
182 //==========\r
183   mWidthOfArrow = mHeightOfArrow = mSizeOfArrow;\r
184 //==========\r
185   int num_index = (int)(std::log((double)num_state)/LOG10) + 1;\r
186   AnsiString as1 = "";\r
187   for (int i = 0; i < num_index; i++) as1 += "0";\r
188   mCanvas->Font->Size = FSIZE_INDEX;\r
189   mWidthOfIndex = mCanvas->TextWidth(as1);\r
190   mHeightOfIndex = mCanvas->TextHeight("0");\r
191 \r
192 //==========\r
193   as1 = "-- + i..00";\r
194   for (int i = 0; i < mPrecision; i++) as1 += "00";\r
195   mCanvas->Font->Size = mFontSizeOfValue;\r
196   mWidthOfValue    = mCanvas->TextWidth(as1);\r
197   mHeightOfValue   = mCanvas->TextHeight("0");\r
198 \r
199 //==========\r
200   as1 = "|";\r
201   for (int i = 0; i < num_qbits; i++) as1 += "0";\r
202   as1 += ">";\r
203   mCanvas->Font->Size = mFontSizeOfQbit;\r
204   mWidthOfQbits  = mCanvas->TextWidth(as1);\r
205   mHeightOfQbits = mCanvas->TextHeight("0");\r
206 }\r
207 //---------------------------------------------------------------------------\r
208 /**\r
209  *\r
210  */\r
211 void\r
212 QDrawGraph::DrawNthRow(const QBits *qbits, const int nq, const int nrow) const {\r
213   int left, bottom, max_height;\r
214   //judge whether this qubits is in viewport;\r
215   int h = mTopMargin + (nrow) * (mRowMargin + GetRowHeight())\r
216           + mTopMargin + mTopWindowMargin;\r
217   if (h > mViewingTop+mHeight || h < (mRowMargin+mViewingTop)) {\r
218     return;\r
219   }\r
220 \r
221   double re = qbits->NthStateR(nq);\r
222   double im = qbits->NthStateI(nq);\r
223 \r
224   max_height = GetRowHeight();\r
225 \r
226   left   = mLeftMargin;\r
227   bottom = mTopMargin + max_height + (max_height + mRowMargin ) * nrow;\r
228   bottom -= mViewingTop;\r
229 \r
230   bottom -= mStrOffset;\r
231   DrawIndex(left, bottom - mHeightOfIndex, nq);\r
232   bottom += mStrOffset;\r
233   left   += mWidthOfIndex + mIAMargin;\r
234 \r
235   DrawArrow(left, bottom - mHeightOfArrow, re, im);\r
236   bottom -= mStrOffset;\r
237   left   += mWidthOfArrow + mAVMargin;\r
238 \r
239   DrawValue(left, bottom - mHeightOfValue, re, im);\r
240   left   += mWidthOfValue + mVQMargin;\r
241   DrawQbit(left, bottom - mHeightOfQbits, qbits->GetNumberOfQBits(), nq);\r
242 }\r
243 //---------------------------------------------------------------------------\r
244 // Drawing Methods\r
245 //---------------------------------------------------------------------------\r
246 /**\r
247  *\r
248  */\r
249 void\r
250 QDrawGraph::DrawIndex(const int x, const int y, const int num) const {\r
251   mCanvas->Brush->Color = clWhite;\r
252   mCanvas->Font->Color = clBlack;\r
253   mCanvas->Font->Size = FSIZE_INDEX;\r
254   mCanvas->TextOut(x, y, IntToStr(num));\r
255 }\r
256 //---------------------------------------------------------------------------\r
257 /**\r
258  *\r
259  */\r
260 void\r
261 QDrawGraph::DrawArrow(const int x, const int y, const double re, const double im) const {\r
262   int default_length = mWidthOfArrow / 2;\r
263   int xfrom = x + default_length;\r
264   int yfrom = y + default_length;\r
265   double norm  = std::sqrt(re * re + im * im);\r
266 \r
267   mCanvas->Brush->Color = clWhite;\r
268   mCanvas->Pen->Color = clBlack;\r
269   mCanvas->Pen->Width = 2;\r
270   mCanvas->Ellipse(x, y, x + mWidthOfArrow, y + mHeightOfArrow);\r
271   mCanvas->Pen->Color = clRed;\r
272   mCanvas->MoveTo(xfrom, yfrom);\r
273 \r
274   default_length *= 0.9;\r
275   if (norm != 0.0)\r
276     mCanvas->LineTo(xfrom + default_length * re / norm, yfrom - default_length * im / norm);\r
277 }\r
278 //---------------------------------------------------------------------------\r
279 /**\r
280  *\r
281  */\r
282 void\r
283 QDrawGraph::DrawValue(const int x, const int y, double re, double im) const {\r
284   std::stringstream ss;\r
285   ss << std::setprecision(mPrecision);\r
286   ss.setf(std::ios::fixed);\r
287   ss << re;\r
288   if (im >= 0){\r
289     ss << " + ";\r
290   } else {\r
291     ss << " - ";\r
292     im = -im;\r
293   }\r
294   ss << im;\r
295   ss << "i";\r
296   mCanvas->Brush->Color = clWhite;\r
297   mCanvas->Font->Color = clRed;\r
298   mCanvas->Font->Size = mFontSizeOfValue;\r
299   mCanvas->TextOut(x, y, ss.str().c_str());\r
300 }\r
301 //---------------------------------------------------------------------------\r
302 /**\r
303  *\r
304  */\r
305 void\r
306 QDrawGraph::DrawQbit(const int x, const int y, const int ntotal, int nth) const {\r
307   string s =">";\r
308   nth = nth < 0 ? -nth : nth;\r
309   for (int i = 0; i < ntotal; i++) {\r
310     if ((nth >> i) & 1) s = "1" + s;\r
311     else s = "0" + s;\r
312   }\r
313   s = "|" + s;\r
314   mCanvas->Brush->Color = clWhite;\r
315   mCanvas->Font->Color = clBlack;\r
316   mCanvas->Font->Size = mFontSizeOfQbit;\r
317   mCanvas->TextOut(x, y, s.c_str());\r
318 }\r
319 //---------------------------------------------------------------------------\r
320 /**\r
321  *  Count How many non-zero number of states\r
322  */\r
323 int\r
324 QDrawGraph::GetNonZeroCount(const QBits *qbits) {\r
325   int n = 0;\r
326   for (int i=0;i<qbits->GetNumberOfStates();i++) {\r
327     double re = qbits->NthStateR(i);\r
328     double im = qbits->NthStateI(i);\r
329     if (re*re+im*im > EPS) {\r
330       n++;\r
331     }\r
332   }\r
333   return n;\r
334 }\r
335 //---------------------------------------------------------------------------\r