Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Plots/ILLitSink.cs @ 11194

Last change on this file since 11194 was 9102, checked in by gkronber, 12 years ago

#1967: ILNumerics source for experimentation

File size: 18.6 KB
Line 
1///
2///    This file is part of ILNumerics Community Edition.
3///
4///    ILNumerics Community Edition - high performance computing for applications.
5///    Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net
6///
7///    ILNumerics Community Edition is free software: you can redistribute it and/or modify
8///    it under the terms of the GNU General Public License version 3 as published by
9///    the Free Software Foundation.
10///
11///    ILNumerics Community Edition is distributed in the hope that it will be useful,
12///    but WITHOUT ANY WARRANTY; without even the implied warranty of
13///    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14///    GNU General Public License for more details.
15///
16///    You should have received a copy of the GNU General Public License
17///    along with ILNumerics Community Edition. See the file License.txt in the root
18///    of your distribution package. If not, see <http://www.gnu.org/licenses/>.
19///
20///    In addition this software uses the following components and/or licenses:
21///
22///    =================================================================================
23///    The Open Toolkit Library License
24///   
25///    Copyright (c) 2006 - 2009 the Open Toolkit library.
26///   
27///    Permission is hereby granted, free of charge, to any person obtaining a copy
28///    of this software and associated documentation files (the "Software"), to deal
29///    in the Software without restriction, including without limitation the rights to
30///    use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
31///    the Software, and to permit persons to whom the Software is furnished to do
32///    so, subject to the following conditions:
33///
34///    The above copyright notice and this permission notice shall be included in all
35///    copies or substantial portions of the Software.
36///
37///    =================================================================================
38///   
39
40using System;
41using System.Collections.Generic;
42using System.Drawing;
43using System.Windows.Forms;
44using ILNumerics.Drawing.Misc;
45using ILNumerics.Drawing.Shapes;
46
47namespace ILNumerics.Drawing.Plots {
48    /// <summary>
49    /// ILNumerics.Drawing plot demonstration, supports multiple shapes, dynamic shape management, light and transparency
50    /// </summary>
51    public class ILLitSink : ILPlot , ILNumerics.Drawing.Interfaces.IILPanelConfigurator {
52
53        #region eventing
54        /// <summary>
55        /// timer tick event handler, called for updates of the interval timer
56        /// </summary>
57        /// <param name="sender">(not used) always this sink plot itself</param>
58        /// <param name="e">(not used)</param>
59        void m_timer_Tick(object sender, EventArgs e) {
60            if (m_timer.Interval > 0 && m_panel != null && m_panel.IsHandleCreated) {
61                m_timer.Stop();
62                LinesPositionOffset += 0.005f * m_gridSpacing;
63                //Opacity = (byte)(255 * (LinesPositionOffset / m_gridSpacing));
64                m_panel.Refresh();
65                m_timer.Start();
66            }
67        }
68        #endregion
69
70        #region attributes
71        float m_lowCut;
72        protected int m_res;
73        ILLineProperties m_gridProperties;
74        protected float m_max;
75        protected float m_gridSpacing;
76        protected float m_linesPositionOffset = 0.5f;
77        bool m_linesUpdateNeeded;
78        Timer m_timer;
79        // the shapes and other plots contained in this plot
80        ILLitSurface m_surface;
81        List<ILLine> m_lines;
82        ILLitSphere m_sphere;
83        #endregion
84
85        #region properties
86        /// <summary>
87        /// get/ set the interval for updates of the moving grid lines [ms]
88        /// </summary>
89        public int Interval {
90            get { return m_timer.Interval; }
91            set {
92                if (value < int.MaxValue && value > 0) {
93                    m_timer.Interval = value;
94                    m_timer.Start(); 
95                } else {
96                    m_timer.Stop();
97                }
98            }
99        }
100        /// <summary>
101        /// Overall opacity for the ground
102        /// </summary>
103        public byte Opacity {
104            get { return m_surface.Opacity; }
105            set {
106                m_surface.Opacity = value;
107                m_surface.Invalidate();
108            }
109        }
110        /// <summary>
111        /// colormap used for coloring the ground
112        /// </summary>
113        public ILColormap Colormap {
114            get { return m_surface.Colormap; }
115            set {
116                m_surface.Colormap = value;
117                m_surface.Invalidate(); 
118            }
119        }
120        /// <summary>
121        /// get reference to the lit sphere
122        /// </summary>
123        public ILLitSphere Sphere {
124            get  { return m_sphere; }
125        }
126        /// <summary>
127        /// get reference to ILLitSurface (i.e. the ground)
128        /// </summary>
129        public ILLitSurface Ground {
130            get { return m_surface; }
131        }
132        /// <summary>
133        /// offset for the grid lines (for moving effect)
134        /// </summary>
135        public float LinesPositionOffset  {
136            get { return m_linesPositionOffset; }
137            set {
138                m_linesPositionOffset = value;
139                if (m_linesPositionOffset > m_gridSpacing) {
140                    m_linesPositionOffset = 0;
141                }
142                m_linesUpdateNeeded = true; 
143                Invalidate();
144            }
145        }
146        #endregion
147
148        #region constructor
149        /// <summary>
150        /// create new lit sink plot, assign default values
151        /// </summary>
152        /// <param name="panel">panel hosting the scene</param>
153        public ILLitSink (ILPanel panel) : this (panel,10,150) {}
154        /// <summary>
155        /// create new lit sink
156        /// </summary>
157        /// <param name="max">lenght of the squared ground</param>
158        /// <param name="panel">panel hosting the scene</param>
159        /// <param name="resolution">horizontal and vertical resolution</param>
160        public ILLitSink(ILPanel panel, float max, int resolution)
161            : base(panel) {
162            m_max = max;
163            m_res = resolution;
164            m_lowCut = -3;
165            m_gridProperties = new ILLineProperties();
166            m_gridProperties.Color = Color.LightBlue;
167            m_gridProperties.Width = 1;
168            m_gridProperties.Antialiasing = false;
169            m_gridProperties.Style = LineStyle.Solid;
170            m_gridSpacing = 1.0f;
171            m_linesUpdateNeeded = false;
172            m_timer = new Timer();
173            m_timer.Interval = int.MaxValue;
174            m_timer.Tick += new EventHandler(m_timer_Tick);
175            createShapes();
176            Invalidate();
177        }
178        #endregion
179
180        #region public API
181        /// <summary>
182        /// called once before rendering the frame, (re)configures the shapes after changes have been made to them
183        /// </summary>
184        /// <remarks><para>ILPlot plots can (not must) override this method. It is called, right before the scene is
185        /// rendered on screen. Since the containing shapes are independently configured, here (in ILPlot) we
186        /// do only need to (re)configure those content of the plot, which must be recreated after changes have been
187        /// applied. In ILLitSink, e.g., changes to the sphere and the ground (ILLitSurface) are directly distributed
188        /// to the related shapes respectively. This happens, when calling any ILShape.Update() overload or after
189        /// ILShape.Invalidate() has been called. Those shapes will than reconfigure itself and must not be handled here. </para>
190        /// <para>In contrast to that, the (moving) grid lines of the sink plot are constantly created and removed.</para>
191        /// </remarks>
192        internal override void Configure() {
193            if (m_linesUpdateNeeded) {
194                updateLines();
195            }
196            base.Configure();
197        }
198
199        /// <summary>
200        /// configure the panel according to default settings of this plot
201        /// </summary>
202        /// <param name="panel">panel hosting the scene</param>
203        /// <remarks>In order to force a custom configuration of the panel,
204        /// the plot implements the IILPanelConfigurator interface. For every plot
205        /// implementing this interface, the panel will be configured by this
206        /// function once the plot was added to the scene/ to the panel graphs collection.
207        /// If the plot does not implement this interface, the panel settings will
208        /// not be altered.</remarks>
209        public void ConfigurePanel(ILPanel panel) {
210            panel.Projection = Projection.Perspective;
211            panel.BackColor = Color.White;
212            panel.BackColorCube = Color.White;
213            panel.Axes.GridVisible = false;
214            panel.Axes.Visible = false;
215            panel.BackgroundFilled = false;
216            panel.AspectRatio = AspectRatioMode.MaintainRatios;
217            panel.PlotBoxScreenSizeMode = PlotBoxScreenSizeMode.Maximum;
218            panel.ClipViewData = false;
219            panel.InteractiveMode = InteractiveModes.Rotating;
220            panel.AutoZoomContent =  AutoZoomOptions.OnStartup;
221            panel.ZoomMode = ZoomModes.Jump;
222 
223        }
224        #endregion
225
226        #region private helper
227
228        private void updateLines() {
229            using (ILScope.Enter()) {
230                // since we do not want the whole panel to get updated for every line, we disable
231                // eventing for this scene graph node
232                EventingSuspend();
233                // the grid is made out of individual line shapes
234                ILCell lines =  Computation.CreateLines(-m_max, m_max,
235                               m_lowCut, 0, m_res, m_gridSpacing, m_linesPositionOffset);
236                // make sure, we have the exact number of lines needed
237                int needCount = lines[0].Size[1] * 2; // x and y direction -> * 2
238                if (m_lines.Count > needCount) {
239                    // if we have to many line shapes, we make unneeded lines invisible
240                    for (int i = m_lines.Count; i-- > needCount; ) {
241                        ILLine shape = m_lines[i];
242                        shape.Visible = false;
243                    }
244                    // just as well, we could instead have removed the shape from both:
245                    // the shape collection of the container (ILSceneGraphInnerNode) and
246                    // the (convenient but redundant) shape collection of the plot:
247                    //Remove(shape);
248                    //m_lines.Remove(shape);
249                }
250                while (m_lines.Count < needCount) {
251                    // we do not have enough lines - so we add new lines here
252                    ILLine newLine = new ILLine(m_panel);
253                    newLine.Properties.Color = m_gridProperties.Color;
254                    newLine.Label.Text = "";
255                    newLine.Properties.Width = m_gridProperties.Width;
256                    newLine.CustomCenter = new ILPoint3Df(0, 0, -200);
257                    Add(newLine);
258                    m_lines.Add(newLine);
259                }
260                // reconfigures all lines
261                for (int i = 0; i < lines[0].Size[1]; i++) {
262                    // x - grid
263                    ILLine line = m_lines[i];
264                    line.Visible = true;
265                    line.Update(lines.GetArray<float>(0)[":", i]
266                                , lines.GetArray<float>(1)[":", i]
267                                , lines.GetArray<float>(2)[":", i]);
268                    // y - grid
269                    line = m_lines[i + lines[0].Size[1]];
270                    line.Update(lines.GetArray<float>(0)[":", i]
271                                 , lines.GetArray<float>(1)[":", i]
272                                 , lines.GetArray<float>(2)[":", i]);
273                }
274                // re-enable eventing
275                EventingResume();
276            }
277        }
278        private void createShapes() {
279            // disable eventing, otherwise, for each line added the whole panel would get reconfigured
280            // which would lead to a poor startup performance
281            EventingSuspend();
282            // the ground is a lit surface
283            if (m_surface == null) {
284                ILCell mesh = Computation.CreateMesh(-m_max, m_max, m_lowCut, 0, m_res);
285                m_surface = new ILLitSurface(m_panel, X : mesh.GetArray<float>(0), Y : mesh.GetArray<float>(1), Z : mesh.GetArray<float>(2), colormap : new ILColormap(Colormaps.Jet));
286                m_surface.Opacity = 190;
287                Add(m_surface);
288            }
289            if (m_lines == null) {
290                // we create all individual lines and save them (redundantly) for later convenient reference.
291                // (the grid is made out of individual line shapes)
292                ILCell lines = Computation.CreateLines(-m_max, m_max,
293                                    m_lowCut, 0, m_res, m_gridSpacing, m_linesPositionOffset);
294                m_lines = new List<ILLine>();
295                for (int i = 0; i < lines[0].Size[1]; i++) {
296                    // x - grid
297                    int len = lines.GetArray<float>(0).S[0];
298                    ILLine line = new ILLine(m_panel,len);
299                    line.Update(lines.GetArray<float>(0)[":", i]
300                                , lines.GetArray<float>(1)[":", i]
301                                , lines.GetArray<float>(2)[":", i]);
302                    line.Properties.Color = m_gridProperties.Color;
303                    line.Label.Text = "";
304                    line.Properties.Width = m_gridProperties.Width;
305                    line.CustomCenter = new ILPoint3Df(0,0,-200);
306                    m_lines.Add(line);
307                    Add(line);
308                    // y - grid
309                    line = new ILLine(m_panel, len);
310                    line.Update(lines.GetArray<float>(0)[":", i]
311                                , lines.GetArray<float>(1)[":", i]
312                                , lines.GetArray<float>(2)[":", i]);
313                    line.Properties.Color = m_gridProperties.Color;
314                    line.Label.Text = "";
315                    line.Properties.Width = m_gridProperties.Width;
316                    line.CustomCenter = new ILPoint3Df(0,0,-200);
317                    m_lines.Add(line);
318                    Add(line);
319                }
320            }
321            // re-enable eventing, still one shape to be added: the sphere, which will cause a reconfiguration
322            // of the whole panel
323            EventingResume();
324            // lit sphere
325            if (m_sphere == null) {
326                m_sphere = new ILLitSphere(m_panel, new ILPoint3Df(0,0,1.4f), 1.8f, Color.FromArgb(190,Color.Gold));
327                Add(m_sphere);
328                m_sphere.Label.Text = "";
329                m_sphere.Opacity = 190;
330            }
331        }
332
333        private class Computation : ILNumerics.ILMath {
334            /// <summary>
335            /// create data needed to create the ground (ILLitSurface)
336            /// </summary>
337            /// <param name="Min">minimum (x and y)</param>
338            /// <param name="Max">maximum (x and y)</param>
339            /// <param name="cut">minimum sinkhole level</param>
340            /// <param name="zNiveau">overall zero level</param>
341            /// <param name="resol">horizontal and vertical resolution</param>
342            /// <param name="result">cell vector with X, Y and Z array</param>
343            public static ILRetCell CreateMesh(
344                                            float Min, float Max,
345                                            float cut, float zNiveau,
346                                            int resol) {
347                using (ILScope.Enter())  {
348                    ILArray<double> x = linspace(Min, Max, resol);
349                    ILArray<double> y = empty();
350                    ILCell ret = new ILCell(3,1);
351                    ret[0] = meshgrid(x, linspace(Max ,Min, resol), y);
352                    ret[1] = y;
353                    // Z coords
354                    ret[2] = max(-1.0 / (ret.GetArray<double>(0) * ret.GetArray<double>(0))
355                                                + (ret.GetArray<double>(1) * ret.GetArray<double>(1)) + zNiveau, cut);
356                    //ret.Add(find(ret[2] == cut));
357                    return ret;
358                }
359            }
360            /// <summary>
361            /// create data needed to create grid lines
362            /// </summary>
363            /// <param name="Min">minimum (x and y)</param>
364            /// <param name="Max">maximum (x and y)</param>
365            /// <param name="cut">minimum sinkhole level</param>
366            /// <param name="zNiveau">overall zero level</param>
367            /// <param name="resol">horizontal and vertical resolution</param>
368            /// <param name="gridSpacing">spacing between adjacent grid lines</param>
369            /// <param name="gridOffset">starting offset for the grid lines at edges</param>
370            /// <param name="result">list of X,Y and Z arrays</param>
371            /// <remarks>Only the X grid is created. Since we only have squared sink ground, the
372            /// same data can be used for the y grid. </remarks>
373            public static ILRetCell CreateLines(
374                                            float Min, float Max,
375                                            float cut, float zNiveau,
376                                            int resol, float gridSpacing,
377                                            float gridOffset) {
378                using (ILScope.Enter()) {
379                    ILCell ret = new ILCell(2,1);
380                    // X coords
381                    ret[0] = repmat(vec<float>(Min + gridOffset, gridSpacing, Max).T, resol, 1);
382                    // Y coords
383                    ret[1] = repmat(linspace<float>(Min, Max, resol).T, 1, ret[0].Size[1]);
384                    // Z coords
385                    ret[2] = max(-1 /   (ret.GetArray<float>(0) * ret.GetArray<float>(0)
386                                       + ret.GetArray<float>(1) * ret.GetArray<float>(1))
387                                       + zNiveau, cut) + MachineParameterSingle.eps;
388                    //ret.Add(zeros(resol, resol) + 10000);
389                    //ret[2][0] += 0.01;
390                    return ret;
391                }
392            }
393        }
394
395        #endregion
396    }
397}
Note: See TracBrowser for help on using the repository browser.