Free cookie consent management tool by TermsFeed Policy Generator

source: branches/HeuristicLab.Problems.GaussianProcessTuning/ILNumerics.2.14.4735.573/Drawing/Plots/ILVectorField2D.cs @ 9102

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

#1967: ILNumerics source for experimentation

File size: 12.2 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.Text;
43using ILNumerics.Drawing.Graphs;
44using ILNumerics.Drawing.Shapes;
45using ILNumerics.Drawing.Misc;
46using ILNumerics.Exceptions;
47using ILNumerics.Drawing.Interfaces;
48using ILNumerics.Drawing.Collections;
49
50namespace ILNumerics.Drawing.Plots {
51    /// <summary>
52    /// visualizes 2D vector fields
53    /// </summary>
54    public sealed class ILVectorField2D : ILPlot, IILPanelConfigurator {
55
56        #region attributes
57        ILLines m_lines;
58        float m_beta = (float)(5 * Math.PI / 180);
59        float m_scaling = 0.9f;
60        ILArray<float> m_data = ILMath.returnType<float>();
61        ICollection<string> m_xLabels;
62        ICollection<string> m_yLabels;
63        #endregion
64
65        #region properties
66        /// <summary>
67        /// Colormap used to map values to colors
68        /// </summary>
69        private ILColormap m_colormap;
70        /// <summary>
71        /// gets reference to data of all vectors or sets it (restricted to same size)
72        /// </summary>
73        public ILRetArray<float> Data {
74            get {
75                return m_data;
76            }
77            set {
78                if (value != null && value.Size.IsSameSize(m_data.Size)) {
79                    m_data.a = value.C;
80                    Invalidate();
81                }
82            }
83        }
84
85        /// <summary>
86        /// get the colormap used for coloring the arrows or sets it
87        /// </summary>
88        public ILColormap Colormap {
89            get { return m_colormap; }
90            set {
91                m_colormap = value;
92                Invalidate();
93            }
94        }
95        /// <summary>
96        /// opening angle for the arrow heads, default: 5 deg
97        /// </summary>
98        public float ArrowHeadAngle {
99            get { return m_beta; }
100            set {
101                m_beta = value;
102                Invalidate();
103            }
104        }
105
106        /// <summary>
107        /// Scaling of arrow length, 1.0: full size; default: 0.9
108        /// </summary>
109        public float ArrowScale {
110            get { return m_scaling; }
111            set {
112                m_scaling = value;
113                Invalidate();
114            }
115        }
116
117        /// <summary>
118        /// enables access to the lines composite shape used for rendering
119        /// </summary>
120        public ILLines LinesShape {
121            get {
122                return m_lines;
123            }
124        }
125
126        /// <summary>
127        /// collection of label texts for x axis
128        /// </summary>
129        public ICollection<string> XLabels {
130            get { return m_xLabels; }
131            set {
132                m_xLabels = value;
133                Invalidate();
134            }
135        }
136
137        /// <summary>
138        /// collection of label texts for y axis
139        /// </summary>
140        public ICollection<string> YLabels {
141            get { return m_yLabels; }
142            set {
143                m_yLabels = value;
144                Invalidate();
145            }
146        }
147
148        #endregion
149
150        #region constructors
151
152        /// <summary>
153        /// create new vector field (2D) plot
154        /// </summary>
155        /// <param name="panel">panel hosting the scene</param>
156        /// <param name="data">3d data array: :;:;0 - X coords of vectors, :;:;1 - Y coords</param>
157        /// <param name="colormap">Colormap used for coloring, on null: Colormaps.ILNumerics is used as default</param>
158        /// <param name="XLabels">labels for X axis, on null: auto labeling</param>
159        /// <param name="YLabels">labels for Y axis, on null: auto labeling</param>
160        public ILVectorField2D(ILPanel panel, ILInArray<float> data
161            , ILColormap colormap, ICollection<string> XLabels
162            , ICollection<string> YLabels)
163            : base(panel) {
164            using (ILScope.Enter(data)) {
165                m_data.a = ILMath.check(data, (a) => { return (a.S[2] == 2 && !a.IsEmpty) ? a : null; }, ErrorMessage: "Invalid parameter: data");
166                m_xLabels = XLabels;
167                m_yLabels = YLabels;
168                m_colormap = colormap;
169                m_lines = new ILLines(m_panel, data.Size[0] * data.Size[1] * 4);
170                m_lines.Shading = ShadingStyles.Interpolate;
171                m_lines.Properties.Width = 2;
172                m_lines.Properties.Antialiasing = true;
173                m_lines.Label.Text = "";
174                ArrowHeadAngle = (float)(10 * Math.PI / 180);
175                Invalidate();
176                Add(m_lines);
177            }
178        }
179        #endregion
180
181        #region public interface
182        /// <summary>
183        /// (internal use) reconfigures the plot after changes
184        /// </summary>
185        internal override void Configure() {
186            using (ILScope.Enter()) {
187                if (m_invalidated) {
188                    ILArray<int> indices = ILMath.empty<int>();
189                    ILArray<float> vertices = Computation.CreateVertices(
190                        m_data, indices, m_beta, m_scaling / 2, m_colormap);
191                    m_lines.Update(vertices["0;:"], vertices["1;:"], vertices["2;:"], indices, ILMath.toint32(vertices["3:5;:"].T));
192                    // configure axes
193                    configureAxis(AxisNames.XAxis, XLabels);
194                    configureAxis(AxisNames.YAxis, YLabels);
195                }
196                base.Configure();
197            }
198        }
199        #endregion
200
201        #region IILPanelConfigurator Members
202        /// <summary>
203        /// configure the panel, called after the plot was added to the scene
204        /// </summary>
205        /// <param name="panel"></param>
206        public void ConfigurePanel(ILPanel panel) {
207            panel.DefaultView.SetDeg(0, 0, 100);
208        }
209
210        #endregion
211
212        #region private helper
213        private void configureAxis(AxisNames axis
214                                    , ICollection<string> values) {
215            ILTickCollection labels = m_panel.Axes[axis].LabeledTicks;
216            if (values != null) {
217                labels.Mode = TickMode.Manual;
218                labels.Clear();
219                int pos = 1;
220                int axisIdx = (axis == AxisNames.XAxis) ?
221                    1 : (axis == AxisNames.YAxis) ?
222                    0 : 1;
223                foreach (string labelString in values) {
224                    if (pos > m_data.Size[axisIdx])
225                        break;
226                    labels.Add(pos++, labelString);
227                }
228            } else {
229                labels.Mode = TickMode.Auto;
230            }
231        }
232        #endregion
233
234        #region computation
235        public class Computation : ILNumerics.ILMath {
236
237            internal static ILRetArray<float> CreateVertices(ILInArray<float> inData
238                                            , ILOutArray<int> outIndices
239                                            , float beta, float scaling
240                                            , ILColormap colormap) {
241                using (ILScope.Enter(inData)) {
242                    // each arrow needs 4 vertices (indexed rendering)
243                    ILArray<float> data = check(inData);
244                    ILArray<int> indices = empty<int>();
245
246                    int numRows = data.Size[0];
247                    int numCols = data.Size[1];
248                    ILArray<float> ret = zeros<float>(4, numCols * numRows, 2);
249                    // prepare indices
250                    indices.a = repmat(new ILArray<int>(new int[] { 0, 2, 1, 2, 3, 2 }, 6, 1), 1, numCols * numRows);
251                    indices.a = indices + repmat(toint32(counter(0.0, 4.0, 1, numCols * numRows)), 6, 1);
252                    indices.a = indices.Reshape(new ILSize(2, numRows * numCols * 3));
253                    // normalize incoming data to length 1.0
254                    ILArray<float> l = sqrt(sum(data * data, 2));
255                    float maxL = (float)max(maxall(l), epsf);
256                    l.a = (l / maxL)[":"].T * scaling;
257                    ILArray<float> alpha = atan2(data[":;:;1"], data[":;:;0"]);
258                    alpha.a = alpha[":"].T;
259                    ILArray<float> x = data[":;:;0"][":"].T * scaling;
260                    ILArray<float> y = data[":;:;1"][":"].T * scaling;
261                    ILArray<float> xO = repmat(linspace<float>(1, numCols, numCols), numRows, 1)[":"].T;
262                    ILArray<float> yO = repmat(linspace<float>(numRows, 1, numRows).T, 1, numCols)[":"].T;
263                    ret["0;:;0"] = xO - x;
264                    ret["1;:;0"] = xO + x - l / 2 * cos(alpha + beta);
265                    ret["2;:;0"] = xO + x;
266                    ret["3;:;0"] = xO + x - l / 2 * cos(alpha - beta);
267
268                    ret["0;:;1"] = yO - y;
269                    ret["1;:;1"] = yO + y - l / 2 * sin(alpha + beta);
270                    ret["2;:;1"] = yO + y;
271                    ret["3;:;1"] = yO + y - l / 2 * sin(alpha - beta);
272
273                    ret["0;0;2"] = 0.0f;
274                    // prepare colors
275                    ret[":;:;3:5"] =
276                        repmat(colormap.Map(l * colormap.Length).Reshape(1, l.Length, 3) * 255, 4, 1, 1);
277                    return ret.Reshape(4 * numRows * numCols, 6).T;
278                }
279            }
280            /// <summary>
281            /// create data for a simple vector field for demonstration purposes
282            /// </summary>
283            /// <param name="numRows">number of rows</param>
284            /// <param name="numCols">number of colums</param>
285            /// <param name="offs">offset, linearly varing values lets the field 'roll'</param>
286            /// <returns>three dimensional data array</returns>
287            public static ILRetArray<float> CreateTestData(int numRows, int numCols, float offs) {
288                using (ILScope.Enter()) {
289                    ILArray<float> Y = repmat(linspace<float>(offs, pi * 2 + offs, numCols), numRows, 1);
290                    ILArray<float> X = cos(Y);
291                    X[":;:;1"] = sin(Y);
292                    // scale vector length
293                    X.a = X * repmat(0.6f + sin(Y) * 0.4f, 1, 1, 2);
294                    return X;
295                }
296            }
297        }
298        #endregion
299
300    }
301}
Note: See TracBrowser for help on using the repository browser.