/// <summary> /// create vertex data [unevenly distributed, depricated] /// </summary> /// <param name="center"></param> /// <param name="radius"></param> /// <param name="horRes"></param> /// <param name="vertRes"></param> /// <param name="indices"></param> /// <returns></returns> public static ILArray <float> CreateVertices(ILPoint3Df center, float radius, int horRes, int vertRes, out ILArray <int> indices) { ILArray <float> phi = repmat(tosingle(linspace(-pi, pi, horRes + 1)), vertRes + 1, 1); ILArray <float> rho = repmat(tosingle(linspace(0, pi, vertRes + 1)).T, 1, horRes + 1); bool dummy; float[] retArr = ILNumerics.Misc.ILMemoryPool.Pool.New <float>((horRes + 1) * (vertRes + 1), false, out dummy); ILArray <float> ret = new ILArray <float>(retArr, vertRes + 1, horRes + 1); // create normals ret[":;:;3"] = sin(phi) * sin(rho); ret[":;:;4"] = cos(phi) * sin(rho); ret[":;:;5"] = cos(rho); // translate + scale vertices ret[":;:;0"] = (ILArray <float>)radius * ret[":;:;3"] + center.X; ret[":;:;1"] = (ILArray <float>)radius * ret[":;:;4"] + center.Y; ret[":;:;2"] = (ILArray <float>)radius * ret[":;:;5"] + center.Z; // create index mappings //horRes--; vertRes--; indices = new ILArray <int>(4, (horRes) * (vertRes)); for (int r = 0, pos = 0; r < vertRes; r++) { for (int c = 0; c < horRes; c++) { indices.SetValue(c + r * (horRes + 1), pos++); indices.SetValue(c + (r + 1) * (horRes + 1), pos++); indices.SetValue((c + 1) + (r + 1) * (horRes + 1), pos++); indices.SetValue((c + 1) + r * (horRes + 1), pos++); } } System.Diagnostics.Debug.Assert(maxall(indices) <= (double)ret[":;:;0"].Dimensions.NumberOfElements); System.Diagnostics.Debug.Assert(minall(indices) >= 0.0); return(ret); }
/// <summary> /// sort data in A along dimension 'dim' /// </summary> /// <param name="A">input array: empty, scalar, vector or matrix</param> /// <param name="descending">Specifies the direction of sorting</param> /// <param name="dim">dimension to sort along</param> /// <param name="Indices">output parameter: returns permutation matrix also</param> /// <returns>sorted array of the same size as A</returns> /// <remarks><para>The data in A will be sorted using the quick sort algorithm. Data /// along the dimension <paramref name="dim"/> will therefore get sorted independently from data /// in the next row/column.</para> /// <para>This overload also returns an array 'Indices' which will hold the indices into the original /// elements <b>after sorting</b>. Elements of 'Indices' are of type double.</para> ///</remarks> public static ILArray <string> sort(ILArray <string> A, out ILArray <double> Indices, int dim, bool descending) { if (object.Equals(A, null)) { throw new Exception("sort: parameter A must not be null"); } if (A.Dimensions.NumberOfDimensions > 2) { throw new ILArgumentException("sort: for element type string only matrices are supported!"); } if (dim < 0 || dim >= A.Dimensions.NumberOfDimensions) { throw new ILArgumentException("sort: invalid dimension argument"); } // early exit: scalar/ empty if (A.IsEmpty || A.IsScalar) { Indices = 0.0; return(A.C); } ILArray <string> ret = new ILArray <string>(new string[A.Dimensions.NumberOfElements], A.Dimensions); int dim1 = dim % A.Dimensions.NumberOfDimensions; int dim2 = (dim1 + 1) % A.Dimensions.NumberOfDimensions; int maxRuns = A.Dimensions[dim2]; ILQueueList <string, double> ql; ILArray <int>[] ind = new ILArray <int> [2]; int [] indI = new int[2]; ILASCIIKeyMapper km = new ILASCIIKeyMapper(); Indices = ILMath.counter(0.0, 1.0, A.Dimensions.ToIntArray()); for (int c = 0; c < maxRuns; c++) { ind[dim2] = c; ind[dim1] = null; ql = ILBucketSort.BucketSort <string, char, double>(A[ind].Values, Indices[ind].Values, km, ILBucketSort.SortMethod.ConstantLength); indI[dim2] = c; if (descending) { for (int i = ql.Count; i-- > 0;) { indI[dim1] = i; ILListItem <string, double> item = ql.Dequeue(); ret.SetValue(item.Data, indI); Indices.SetValue(item.m_index, indI); } } else { for (int i = 0; ql.Count > 0; i++) { indI[dim1] = i; ILListItem <string, double> item = ql.Dequeue(); ret.SetValue(item.Data, indI); Indices.SetValue(item.m_index, indI); } } } return(ret); }
public ILArray <T> Load <T>() { int i = 0; int nrow = 0; int ncol = 0; string header = ""; GetCotentInfo(ref nrow, ref ncol, ref header); ILArray <T> array = ILMath.zeros <T>(nrow, ncol); StreamReader sr = new StreamReader(_Filename); try { header = sr.ReadLine(); string line = ""; for (i = 0; i < nrow; i++) { line = sr.ReadLine(); var buf = TypeConverterEx.Split <T>(line); for (int j = 0; j < ncol; j++) { array.SetValue(buf[j], i, j); } } } catch (Exception ex) { ErrorMessage = ex.Message; } sr.Close(); return(array); }
/// <summary> /// computes normalized magnitudes out of raw samples /// </summary> /// <param name="buffer">sample buffer from naudio</param> /// <param name="buffLen">number of samples</param> /// <param name="fftLen">number of samples for fft </param> /// <param name="MaxValue">[output] index of maximum magnitude value</param> /// <returns>normalized magnitudes (for Y axis)</returns> public static ILRetArray <float> GetMagnitudes(byte[] buffer, int buffLen, int fftLen, ILOutArray <int> MaxValue) { using (ILScope.Enter()) { // how many samples returned from naudio? int newSampleLen = Math.Min(buffLen / 2, fftLen); // create a temporary array for the samples ILArray <float> tmp = zeros <float>(fftLen, 1); // transfer byte[] buffer to temp array for (int s = 0; s < newSampleLen; s++) { tmp.SetValue((short)(buffer[s * 2 + 1] << 8 | buffer[s * 2]), s); } // transform into frequency domain, we use a simple cosine window here ILArray <float> cosWin = sin(pif * counter <float>(0f, 1f, tmp.Length, 1) / (tmp.Length - 1)); //ILArray<float> hamm = (0.54f - 0.46f * cos(2f * pif * counter<float>(0f,1f,ret.Length,1)/ (ret.Length - 1))); // compute the magnitudes, keep relevant part only tmp.a = abs(fft(tmp * cosWin)[r(0, end / 2 + 1)]); // some poor mans high pass filter if (tmp.Length > 20) { tmp["0:20"] = tmp[20]; } // compute max values ILArray <int> maxTmpId = 0; // -> we do want the indices ILArray <float> maxTmp = sort(tmp, Indices: maxTmpId, descending: true); // assign to output parameter MaxValue.a = maxTmpId["0:4"]; // return magnitudes Y values return(tmp.T); } }
/// <summary> /// map all elements in A into final colors /// </summary> /// <param name="A">array with elements to map</param> /// <returns>colors as ILArray, the i-th row represents the color for the i-th element of A as RGB tripel.</returns> public ILArray <float> Map(ILArray <float> A) { ILArray <float> ret = new ILArray <float>(A.Dimensions.NumberOfElements, 3); float min, max; if (!A.GetLimits(out min, out max) || min == max) { // special case: all constant: eturn middle of colormap return(ILMath.repmat(m_map[m_map.Length / 2, null], ret.Dimensions[0], 1)); } float dist = (m_map.Dimensions[0] - 1) / (A.MaxValue - min); for (int i = 0; i < ret.Dimensions[0]; i++) { double index = (double)(A.GetValue(i) - min) * dist; if (index >= m_map.Dimensions[0] - 1) { ret[i, null] = m_map["end;:"]; continue; } else if (index < 0) { ret[i, null] = m_map["0;:"]; continue; } int find = (int)Math.Floor(index); if (find == index) { ret[i, null] = m_map[find, null]; continue; } // interpolate index = index - find; float r1 = m_map.GetValue(find, 0); float g1 = m_map.GetValue(find, 1); float b1 = m_map.GetValue(find, 2); r1 = (float)(index * (m_map.GetValue(find + 1, 0) - r1) + r1); g1 = (float)(index * (m_map.GetValue(find + 1, 1) - g1) + g1); b1 = (float)(index * (m_map.GetValue(find + 1, 2) - b1) + b1); ret.SetValue(r1, i, 0); ret.SetValue(g1, i, 1); ret.SetValue(b1, i, 2); } return(ret); }
/// <summary> /// Multidimensional scaling/PCoA: transform distances to points in a coordinate system. /// </summary> /// <param name="input">A matrix of pairwise distances. Zero indicates identical objects.</param> /// <returns>A matrix, the columns of which are coordinates in the nth dimension. /// The rows are in the same order as the input.</returns> public static ILArray <double> Scale(ILArray <double> input) { int n = input.Length; ILArray <double> p = ILMath.eye <double>(n, n) - ILMath.repmat(1.0 / n, n, n); ILArray <double> a = -.5 * ILMath.multiplyElem(input, input); ILArray <double> b = ILMath.multiply(p, a, p); ILArray <complex> V = ILMath.empty <complex>(); ILArray <complex> E = ILMath.eig((b + b.T) / 2, V); ILArray <int> i = ILMath.empty <int>(); ILArray <double> e = ILMath.sort(ILMath.diag(ILMath.real(E)), i); e = ILMath.flipud(e); i = ILMath.toint32(ILMath.flipud(ILMath.todouble(i))); ILArray <int> keep = ILMath.empty <int>(); for (int j = 0; j < e.Length; j++) { if (e[j] > 0.000000001) { keep.SetValue(j, keep.Length); } } ILArray <double> Y; if (ILMath.isempty(keep)) { Y = ILMath.zeros(n, 1); } else { Y = ILMath.zeros <double>(V.S[0], keep.Length); for (int j = 0; j < keep.Length; j++) { Y[ILMath.full, j] = ILMath.todouble(-V[ILMath.full, i[keep[j]]]); } Y = ILMath.multiply(Y, ILMath.diag(ILMath.sqrt(e[keep]))); } ILArray <int> maxind = ILMath.empty <int>(); ILMath.max(ILMath.abs(Y), maxind, 0); int d = Y.S[1]; ILArray <int> indices = maxind + ILMath.toint32(ILMath.array <int>(SteppedRange(0, n, (d - 1) * n))); ILArray <double> colsign = ILMath.sign(Y[indices]); for (int j = 0; j < Y.S[1]; j++) { Y[ILMath.full, j] = Y[ILMath.full, j] * colsign[j]; } return(Y); }
private static ILArray <double> ILArrayFromArray(double[][] array) { int dim1 = array.GetLength(0); int dim2 = (dim1 >= 1 ? array[0].Length : 0); ILArray <double> ilArray = (dim1 == 0 || dim2 == 0 ? ILMath.empty(dim1, dim2) : ILMath.zeros(dim1, dim2)); for (int i = 0; i <= dim1 - 1; i++) { for (int j = 0; j <= dim2 - 1; j++) { ilArray.SetValue(array[i][j], i, j); } } return(ilArray); }
public static ILArray<float> CreateData(int rX, int rY) { Bitmap heightmap = Resource1.saltlake; int x = Math.Min(heightmap.Size.Width,rX); int y = Math.Min(heightmap.Size.Height,rY); ILArray<float> ret = new ILArray<float>(rX, rY); for (int c = 0; c < x; c++) { for (int r = 0; r < y; r++) { Color val = heightmap.GetPixel(c,r); ret.SetValue(val.GetBrightness(),r,c); } } float maxVal = (float)maxall(abs(ret)); if (maxVal != 0) ret /= maxVal; ret *= 50; return ret; // ["0:2:end;0:2:end"]; }
public static ILArray <float> CreateData(int rX, int rY) { Bitmap heightmap = Resource1.saltlake; int x = Math.Min(heightmap.Size.Width, rX); int y = Math.Min(heightmap.Size.Height, rY); ILArray <float> ret = new ILArray <float>(rX, rY); for (int c = 0; c < x; c++) { for (int r = 0; r < y; r++) { Color val = heightmap.GetPixel(c, r); ret.SetValue(val.GetBrightness(), r, c); } } float maxVal = (float)maxall(abs(ret)); if (maxVal != 0) { ret /= maxVal; } ret *= 50; return(ret); // ["0:2:end;0:2:end"]; }
/// <summary> /// create colormap /// </summary> /// <param name="map">map specification</param> /// <param name="len">len of colormap</param> /// <returns>colormap (matrix with size [len,3])</returns> internal static ILArray<float> CreateMap(Colormaps map, int len) { ILArray<float> ret = null; ILArray<double> retd; // helper var int n; switch (map) { case Colormaps.Autumn: ret = tosingle(horzcat(ones(len,1),linspace(0,1.0,len).T,zeros(len,1))); break; case Colormaps.Bone: ret = CreateMap( Colormaps.Hot)[":;end:-1:0"]; ret = (tosingle(repmat(linspace(0,1.0,len).T,1,3)*7.0) + ret)/8.0f; break; case Colormaps.Colorcube: throw new NotImplementedException("ILColormap: sorry, colorcube must be implemented!"); break; case Colormaps.Cool: retd = horzcat(linspace(0,1.0,len).T,linspace(1.0,0.0,len).T,ones(len,1)); ret = tosingle(retd); break; case Colormaps.Copper: retd = linspace(0,1.0,len).T; ret = ILArray<float>.empty(); ret = tosingle(min(1.0,retd*1.25)); ret[":;1"] = tosingle(retd*0.782); ret[":;2"] = tosingle(retd*0.4975); break; case Colormaps.Flag: retd = new double[,]{{1, 0, 0},{1, 1, 1},{0, 0, 1},{0, 0, 0}}; retd = repmat(retd.T,(int)ceil((double)len/retd.Dimensions[1]),1); ret = tosingle(retd[vector(0,len-1),null]); break; case Colormaps.Gray: ret = tosingle(repmat(linspace(0,1.0,len).T,1,3)); break; case Colormaps.Hot: n = (int)fix(len/8.0*3); retd = zeros(len,3); ILArray<double> rng = vector(0,n-1); retd[rng,0] = linspace (0,1.0,n); retd[vector(n,len-1),0] = 1.0; retd[rng+n,1] = linspace (0,1.0,n); retd[vector(2*n,len-1),1] = 1.0; rng = vector(len-2*n,len-1); retd[rng,2] = linspace (0,1.0,rng.Length); ret = tosingle(retd); break; case Colormaps.Hsv: n = len / 6; // red ILArray<double> peak = 2.0-abs(linspace(2,-2,4*n)); retd = zeros(len,3); retd[vector(len - peak.Length,len-1),0] = peak; retd[vector(0 ,4*n-1),1] = peak; retd[vector(0 ,2*n-1),2] = peak[vector(2*n,4*n-1)]; retd[vector(len - 2*n,len-1),2] = peak[vector(0 ,2*n-1)]; retd[retd > 1] = 1; ret = tosingle(retd); break; case Colormaps.ILNumerics: ret = new ILArray<float>(len,3); int tmp; ILColorProvider cprov = new ILColorProvider(0.0f,0.5f,1.0f); rng = linspace(ILColorProvider.MAXHUEVALUE,0.0,len); for (int i = 0; i < len; i++) { tmp = cprov.H2RGB((float)rng[i]); ret.SetValue((float)(tmp>>16 & 255),i,0); ret.SetValue((float)(tmp>>8 & 255),i,1); ret.SetValue((float)(tmp & 255),i,2); } ret /= 255.0f; break; case Colormaps.Jet: n = len / 8; // red peak = 1.5-abs(linspace(1.5,-1.5,6*n)); retd = zeros(len,3); retd[vector(0 ,5*n-1),0] = peak[vector(n,6*n-1)]; retd[vector(n ,7*n-1),1] = peak; retd[vector(3*n,8*n-1),2] = peak[vector(0,5*n-1)]; retd[retd > 1] = 1; ret = tosingle(retd); break; case Colormaps.Lines: retd = randn(len,3); retd /= maxall(abs(retd)); ret = tosingle(1.0-abs(retd)); break; case Colormaps.Pink: ret = CreateMap(Colormaps.Hot,len); ret = sqrt((repmat(tosingle(linspace(0,1.0,len).T),1,3)*2.0f + ret)/3.0f); break; case Colormaps.Prism: retd = new double[,]{{1, 0, 0},{1, 0.5, 0},{1, 1, 0},{0, 1, 0},{0, 0, 1},{2/3.0, 0, 1}}; retd = repmat(retd.T,(int)ceil((double)len/retd.Dimensions[1]),1); ret = tosingle(retd[vector(0,len-1),null]); break; case Colormaps.Spring: retd = ones(len,1); retd[":;1"] = linspace(0.0,1.0,len); retd[":;2"] = linspace(1.0,0.0,len); ret = tosingle(retd); break; case Colormaps.Summer: retd = linspace(0.0,1.0,len).T; retd[":;1"] = 0.5+retd/2.0;; retd[":;2"] = ones(len,1)*0.4; ret = tosingle(retd); break; case Colormaps.White: ret = tosingle(ones(len,3)); break; case Colormaps.Winter: retd = zeros(len,1); retd[":;2"] = 0.5+(1.0-linspace(0.0,1.0,len))/2.0; retd[":;1"] = linspace(0.0,1.0,len); ret = tosingle(retd); break; } return ret; }
/// <summary> /// map all elements in A into final colors /// </summary> /// <param name="A">array with elements to map</param> /// <returns>colors as ILArray, the i-th row represents the color for the i-th element of A as RGB tripel.</returns> public ILArray<float> Map (ILArray<float> A) { ILArray<float> ret = new ILArray<float>(A.Dimensions.NumberOfElements,3); float min, max; if (!A.GetLimits(out min, out max) || min == max) { // special case: all constant: eturn middle of colormap return ILMath.repmat(m_map[m_map.Length / 2, null], ret.Dimensions[0], 1); } float dist = (m_map.Dimensions[0]-1) / (A.MaxValue - min); for (int i = 0; i < ret.Dimensions[0]; i++) { double index = (double)(A.GetValue(i)-min)*dist; if (index >= m_map.Dimensions[0] - 1) { ret[i, null] = m_map["end;:"]; continue; } else if (index < 0) { ret[i, null] = m_map["0;:"]; continue; } int find = (int)Math.Floor(index); if (find == index) { ret[i,null] = m_map[find,null]; continue; } // interpolate index = index - find; float r1 = m_map.GetValue(find,0); float g1 = m_map.GetValue(find,1); float b1 = m_map.GetValue(find,2); r1 = (float)(index*(m_map.GetValue(find+1,0)-r1)+r1); g1 = (float)(index*(m_map.GetValue(find+1,1)-g1)+g1); b1 = (float)(index*(m_map.GetValue(find+1,2)-b1)+b1); ret.SetValue(r1,i,0); ret.SetValue(g1,i,1); ret.SetValue(b1,i,2); } return ret; }
/// <summary> /// create colormap /// </summary> /// <param name="map">map specification</param> /// <param name="len">len of colormap</param> /// <returns>colormap (matrix with size [len,3])</returns> internal static ILArray <float> CreateMap(Colormaps map, int len) { ILArray <float> ret = null; ILArray <double> retd; // helper var int n; switch (map) { case Colormaps.Autumn: ret = tosingle(horzcat(ones(len, 1), linspace(0, 1.0, len).T, zeros(len, 1))); break; case Colormaps.Bone: ret = CreateMap(Colormaps.Hot)[":;end:-1:0"]; ret = (tosingle(repmat(linspace(0, 1.0, len).T, 1, 3) * 7.0) + ret) / 8.0f; break; case Colormaps.Colorcube: throw new NotImplementedException("ILColormap: sorry, colorcube must be implemented!"); break; case Colormaps.Cool: retd = horzcat(linspace(0, 1.0, len).T, linspace(1.0, 0.0, len).T, ones(len, 1)); ret = tosingle(retd); break; case Colormaps.Copper: retd = linspace(0, 1.0, len).T; ret = ILArray <float> .empty(); ret = tosingle(min(1.0, retd * 1.25)); ret[":;1"] = tosingle(retd * 0.782); ret[":;2"] = tosingle(retd * 0.4975); break; case Colormaps.Flag: retd = new double[, ] { { 1, 0, 0 }, { 1, 1, 1 }, { 0, 0, 1 }, { 0, 0, 0 } }; retd = repmat(retd.T, (int)ceil((double)len / retd.Dimensions[1]), 1); ret = tosingle(retd[vector(0, len - 1), null]); break; case Colormaps.Gray: ret = tosingle(repmat(linspace(0, 1.0, len).T, 1, 3)); break; case Colormaps.Hot: n = (int)fix(len / 8.0 * 3); retd = zeros(len, 3); ILArray <double> rng = vector(0, n - 1); retd[rng, 0] = linspace(0, 1.0, n); retd[vector(n, len - 1), 0] = 1.0; retd[rng + n, 1] = linspace(0, 1.0, n); retd[vector(2 * n, len - 1), 1] = 1.0; rng = vector(len - 2 * n, len - 1); retd[rng, 2] = linspace(0, 1.0, rng.Length); ret = tosingle(retd); break; case Colormaps.Hsv: n = len / 6; // red ILArray <double> peak = 2.0 - abs(linspace(2, -2, 4 * n)); retd = zeros(len, 3); retd[vector(len - peak.Length, len - 1), 0] = peak; retd[vector(0, 4 * n - 1), 1] = peak; retd[vector(0, 2 * n - 1), 2] = peak[vector(2 * n, 4 * n - 1)]; retd[vector(len - 2 * n, len - 1), 2] = peak[vector(0, 2 * n - 1)]; retd[retd > 1] = 1; ret = tosingle(retd); break; case Colormaps.ILNumerics: ret = new ILArray <float>(len, 3); int tmp; ILColorProvider cprov = new ILColorProvider(0.0f, 0.5f, 1.0f); rng = linspace(ILColorProvider.MAXHUEVALUE, 0.0, len); for (int i = 0; i < len; i++) { tmp = cprov.H2RGB((float)rng[i]); ret.SetValue((float)(tmp >> 16 & 255), i, 0); ret.SetValue((float)(tmp >> 8 & 255), i, 1); ret.SetValue((float)(tmp & 255), i, 2); } ret /= 255.0f; break; case Colormaps.Jet: n = len / 8; // red peak = 1.5 - abs(linspace(1.5, -1.5, 6 * n)); retd = zeros(len, 3); retd[vector(0, 5 * n - 1), 0] = peak[vector(n, 6 * n - 1)]; retd[vector(n, 7 * n - 1), 1] = peak; retd[vector(3 * n, 8 * n - 1), 2] = peak[vector(0, 5 * n - 1)]; retd[retd > 1] = 1; ret = tosingle(retd); break; case Colormaps.Lines: retd = randn(len, 3); retd /= maxall(abs(retd)); ret = tosingle(1.0 - abs(retd)); break; case Colormaps.Pink: ret = CreateMap(Colormaps.Hot, len); ret = sqrt((repmat(tosingle(linspace(0, 1.0, len).T), 1, 3) * 2.0f + ret) / 3.0f); break; case Colormaps.Prism: retd = new double[, ] { { 1, 0, 0 }, { 1, 0.5, 0 }, { 1, 1, 0 }, { 0, 1, 0 }, { 0, 0, 1 }, { 2 / 3.0, 0, 1 } }; retd = repmat(retd.T, (int)ceil((double)len / retd.Dimensions[1]), 1); ret = tosingle(retd[vector(0, len - 1), null]); break; case Colormaps.Spring: retd = ones(len, 1); retd[":;1"] = linspace(0.0, 1.0, len); retd[":;2"] = linspace(1.0, 0.0, len); ret = tosingle(retd); break; case Colormaps.Summer: retd = linspace(0.0, 1.0, len).T; retd[":;1"] = 0.5 + retd / 2.0;; retd[":;2"] = ones(len, 1) * 0.4; ret = tosingle(retd); break; case Colormaps.White: ret = tosingle(ones(len, 3)); break; case Colormaps.Winter: retd = zeros(len, 1); retd[":;2"] = 0.5 + (1.0 - linspace(0.0, 1.0, len)) / 2.0; retd[":;1"] = linspace(0.0, 1.0, len); ret = tosingle(retd); break; } return(ret); }
public static ILLitTriangles LoadSTL(ILPanel panel, string par1) { string[] lines; // modify according the number format in the stl file! Here: 0.12345 System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US").NumberFormat; if (String.IsNullOrEmpty(par1.Trim()) || !System.IO.File.Exists(par1)) { par1 = Resource1.gear; lines = par1.Split('\n'); } else { lines = System.IO.File.ReadAllLines(par1); } #region parse and load vertices // predefine array (for performance) ILArray<float> vertexData = new ILArray<float>(6, (int)(lines.Length / 2.0)); int count = 0; float NX = 0, NY = 0, NZ = 0; foreach (string line in lines) { int start = line.IndexOf("vertex"); if (start >= 0) { // vertex found start += 6; string[] valsS = line.Substring(start).Trim().Split(new char[] {' '},StringSplitOptions.RemoveEmptyEntries); if (valsS != null && valsS.Length >= 3) { float X, Y, Z; // vertex is valid (may be..) X = float.Parse(valsS[0], nfi); Y = float.Parse(valsS[1], nfi); Z = float.Parse(valsS[2], nfi); // store for later vertexData.SetValue(X, 0, count); vertexData.SetValue(Y, 1, count); vertexData.SetValue(Z, 2, count); vertexData.SetValue(NX, 3, count); vertexData.SetValue(NY, 4, count); vertexData.SetValue(NZ, 5, count); count++; } } else { start = line.IndexOf("normal"); if (start >= 0) { // normal entry found start += 6; string[] valsN = line.Substring(start).Trim().Split(' '); if (valsN != null && valsN.Length == 3) { // normal is valid, cache it NX = float.Parse(valsN[0], nfi); NY = float.Parse(valsN[1], nfi); NZ = float.Parse(valsN[2], nfi); } } } } // truncate temp array, remove trail not needed vertexData = vertexData[":;0:" + (count - 1)]; #endregion #region create + configure composite shape ILLitTriangles ret = new ILLitTriangles( panel // panel hosting the scene , vertexData["0;:"] // X components , vertexData["1;:"] // Y components , vertexData["2;:"]); // Z components ret.AutoNormals = false; for (int i = 0; i < ret.Vertices.Length; i++) { ret.Vertices[i].Normal = new ILPoint3Df( vertexData.GetValue(3, i) , vertexData.GetValue(4, i) , vertexData.GetValue(5, i)); ret.Vertices[i].Color = Color.FromArgb(255, 100, 100, 100); ret.Vertices[i].Alpha = 255; } #endregion return ret; }
/// <summary> /// generic sort algorithm in A along dimension 'dim' /// </summary> /// <param name="A">input array: empty, scalar, vector or matrix</param> /// <param name="descending">Specifies the direction of sorting</param> /// <param name="dim">dimension to sort along</param> /// <param name="Indices">input/output parameter: the values in Indices will be returned in the same sorted order as the elements in A. This can be used to derive a permutation matrix of the sorting process.</param> /// <param name="keymapper">Instancce of an object of type ILKeyMapper. This object must /// be derived ILKeyMapper<T,SubelementType> and match the generic argument <typeparamref name="T"/>. It will be /// used to split single elements into its subelements and map their content into bucket numbers. For all /// reference types except those of type string you will have to write your own ILKeyMapper class for that purpose.</param> /// <returns>sorted array of the same size as A</returns> /// <remarks><para>The data in A will be sorted using the quick sort algorithm. Data /// along the dimension <paramref name="dim"/> will therefore get sorted independently from data /// in the next row/column.</para> /// <para>This overload also returns an array 'Indices' which will hold the indices into the original /// elements <b>after sorting</b>. Elements of 'Indices' are always of type int.</para> /// <para>This generic version is able to sort arbitrary element types. Even user defined reference types can be sorted /// by specifying a user defined ILKeyMapper class instance. Also the type of Indices may be arbitrarily choosen. In difference /// to the regular sort function overload, Indices must manually given to the function on the beginning. The given array's /// elements will than be sorted in the same order as the input array A and returned.</para> /// <para>By using this overload you may use the same permutation matrix several times to reflect the /// manipulations done to A due multiple sort processes. The Indices given will directly get used for the current sorting /// without looking at their initial order.</para> /// </remarks> public static ILArray <T> sort <T, S, I> (ILArray <T> A, ref ILArray <I> Indices, int dim, bool descending, ILKeyMapper <T, S> keymapper) { if (object.Equals(A, null)) { throw new Exception("sort: parameter A must not be null"); } if (A.Dimensions.NumberOfDimensions > 2) { throw new ILArgumentException("sort: for generic element type - only matrices are supported!"); } if (dim < 0 || dim >= A.Dimensions.NumberOfDimensions) { throw new ILArgumentException("sort: invalid dimension argument"); } if (keymapper == null) { throw new ILArgumentException("sort: the keymapper argument must not be null"); } if (object.Equals(Indices, null) || !Indices.Dimensions.IsSameSize(A.Dimensions)) { throw new ILArgumentException("sort: Indices argument must have same size/shape as input A"); } // early exit: scalar/ empty if (A.IsEmpty || A.IsScalar) { Indices = default(I); return(A.C); } ILArray <T> ret = new ILArray <T>(new T[A.Dimensions.NumberOfElements], A.Dimensions); int dim1 = dim % A.Dimensions.NumberOfDimensions; int dim2 = (dim1 + 1) % A.Dimensions.NumberOfDimensions; int maxRuns = A.Dimensions[dim2]; ILQueueList <T, I> ql; ILArray <int>[] ind = new ILArray <int> [2]; int [] indI = new int[2]; for (int c = 0; c < maxRuns; c++) { ind[dim2] = c; ind[dim1] = null; ql = ILBucketSort.BucketSort <T, S, I>(A[ind].Values, Indices[ind].Values, keymapper, ILBucketSort.SortMethod.ConstantLength); indI[dim2] = c; if (descending) { for (int i = ql.Count; i-- > 0;) { indI[dim1] = i; ILListItem <T, I> item = ql.Dequeue(); ret.SetValue(item.Data, indI); Indices.SetValue(item.m_index, indI); } } else { for (int i = 0; ql.Count > 0; i++) { indI[dim1] = i; ILListItem <T, I> item = ql.Dequeue(); ret.SetValue(item.Data, indI); Indices.SetValue(item.m_index, indI); } } } return(ret); }
private static void _ <T>(this ILArray <T> ilArray, int index, char equalitySign, T value) { ilArray.SetValue(value, index - 1); }
/// <summary> /// increase the number of triangles by doubling existing triangles /// </summary> /// <param name="vertices">vertices</param> /// <param name="triangles">triangle index definitions</param> /// <param name="iterations">number of iterations, each iteration will make 4 triangles out of each triangle</param> /// <param name="outVertices">output, vertices.</param> /// <param name="outTriangles">output, triangles</param> /// <remarks><para>Incoming triangles are expected not to be degenerated. This means: /// Every edge is used only twice at most. No triangle shares more than 2 /// corners with some other triangle. </para> /// <para>None of the incoming arrays will get altered</para></remarks> public static void Triangularize(ILArray <float> vertices, ILArray <int> triangles, int iterations, out ILArray <float> outVertices, out ILArray <int> outTriangles) { int numVertices = vertices.Dimensions[1]; int numTriangles = triangles.Dimensions[1]; outVertices = vertices.C; outTriangles = triangles.C; // beeing pessimistic: expect to create a larger number of vertices than probable outVertices[0, numVertices * 2] = 0; outTriangles[0, numTriangles * 2] = 0; int triIndLast = numTriangles; int vertIndLast = numVertices; for (int it = 0; it < iterations; it++) { int triIndItEnd = triIndLast; for (int triInd = 0; triInd < triIndItEnd; triInd++) { int vertInd0 = outTriangles.GetValue(0, triInd); int vertInd1 = outTriangles.GetValue(1, triInd); int vertInd2 = outTriangles.GetValue(2, triInd); // create new vertices float v0x = (outVertices.GetValue(0, vertInd0) + outVertices.GetValue(0, vertInd1)) / 2f; float v0y = (outVertices.GetValue(1, vertInd0) + outVertices.GetValue(1, vertInd1)) / 2f; float v0z = (outVertices.GetValue(2, vertInd0) + outVertices.GetValue(2, vertInd1)) / 2f; float v1x = (outVertices.GetValue(0, vertInd1) + outVertices.GetValue(0, vertInd2)) / 2f; float v1y = (outVertices.GetValue(1, vertInd1) + outVertices.GetValue(1, vertInd2)) / 2f; float v1z = (outVertices.GetValue(2, vertInd1) + outVertices.GetValue(2, vertInd2)) / 2f; float v2x = (outVertices.GetValue(0, vertInd2) + outVertices.GetValue(0, vertInd0)) / 2f; float v2y = (outVertices.GetValue(1, vertInd2) + outVertices.GetValue(1, vertInd0)) / 2f; float v2z = (outVertices.GetValue(2, vertInd2) + outVertices.GetValue(2, vertInd0)) / 2f; #region new vertex exists already? TODO: This needs to be replaced with a b-tree implementation!! int newVertID0 = -1; int newVertID1 = -1; int newVertID2 = -1; for (int vi = 0; vi < vertIndLast; vi++) { float tmpX = outVertices.GetValue(0, vi); float tmpY = outVertices.GetValue(1, vi); float tmpZ = outVertices.GetValue(2, vi); if (tmpX == v0x && tmpY == v0y && tmpZ == v0z) { newVertID0 = vi; } if (tmpX == v1x && tmpY == v1y && tmpZ == v1z) { newVertID1 = vi; } if (tmpX == v2x && tmpY == v2y && tmpZ == v2z) { newVertID2 = vi; } if (newVertID0 >= 0 && newVertID1 >= 0 && newVertID2 >= 0) { break; } } #endregion if (newVertID0 < 0) { newVertID0 = vertIndLast++; outVertices[0, newVertID0] = v0x; outVertices[1, newVertID0] = v0y; outVertices[2, newVertID0] = v0z; } if (newVertID1 < 0) { newVertID1 = vertIndLast++; outVertices[0, newVertID1] = v1x; outVertices[1, newVertID1] = v1y; outVertices[2, newVertID1] = v1z; } if (newVertID2 < 0) { newVertID2 = vertIndLast++; outVertices[0, newVertID2] = v2x; outVertices[1, newVertID2] = v2y; outVertices[2, newVertID2] = v2z; } // create new triangles outTriangles.SetValue(newVertID0, 1, triInd); outTriangles.SetValue(newVertID2, 2, triInd); outTriangles.SetValue(newVertID2, 0, triIndLast); outTriangles.SetValue(newVertID1, 1, triIndLast); outTriangles.SetValue(vertInd2, 2, triIndLast++); outTriangles.SetValue(newVertID2, 0, triIndLast); outTriangles.SetValue(newVertID0, 1, triIndLast); outTriangles.SetValue(newVertID1, 2, triIndLast++); outTriangles.SetValue(newVertID0, 0, triIndLast); outTriangles.SetValue(vertInd1, 1, triIndLast); outTriangles.SetValue(newVertID1, 2, triIndLast++); } } outVertices = outVertices[":;0:" + (vertIndLast - 1)]; outTriangles = outTriangles[":;0:" + (triIndLast - 1)]; }
public static ILLitTriangles LoadSTL(ILPanel panel, string par1) { string[] lines; // modify according the number format in the stl file! Here: 0.12345 System.Globalization.NumberFormatInfo nfi = new System.Globalization.CultureInfo("en-US").NumberFormat; if (String.IsNullOrEmpty(par1.Trim()) || !System.IO.File.Exists(par1)) { par1 = Resource1.gear; lines = par1.Split('\n'); } else { lines = System.IO.File.ReadAllLines(par1); } #region parse and load vertices // predefine array (for performance) ILArray <float> vertexData = new ILArray <float>(6, (int)(lines.Length / 2.0)); int count = 0; float NX = 0, NY = 0, NZ = 0; foreach (string line in lines) { int start = line.IndexOf("vertex"); if (start >= 0) { // vertex found start += 6; string[] valsS = line.Substring(start).Trim().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (valsS != null && valsS.Length >= 3) { float X, Y, Z; // vertex is valid (may be..) X = float.Parse(valsS[0], nfi); Y = float.Parse(valsS[1], nfi); Z = float.Parse(valsS[2], nfi); // store for later vertexData.SetValue(X, 0, count); vertexData.SetValue(Y, 1, count); vertexData.SetValue(Z, 2, count); vertexData.SetValue(NX, 3, count); vertexData.SetValue(NY, 4, count); vertexData.SetValue(NZ, 5, count); count++; } } else { start = line.IndexOf("normal"); if (start >= 0) { // normal entry found start += 6; string[] valsN = line.Substring(start).Trim().Split(' '); if (valsN != null && valsN.Length == 3) { // normal is valid, cache it NX = float.Parse(valsN[0], nfi); NY = float.Parse(valsN[1], nfi); NZ = float.Parse(valsN[2], nfi); } } } } // truncate temp array, remove trail not needed vertexData = vertexData[":;0:" + (count - 1)]; #endregion #region create + configure composite shape ILLitTriangles ret = new ILLitTriangles( panel // panel hosting the scene , vertexData["0;:"] // X components , vertexData["1;:"] // Y components , vertexData["2;:"]); // Z components ret.AutoNormals = false; for (int i = 0; i < ret.Vertices.Length; i++) { ret.Vertices[i].Normal = new ILPoint3Df( vertexData.GetValue(3, i) , vertexData.GetValue(4, i) , vertexData.GetValue(5, i)); ret.Vertices[i].Color = Color.FromArgb(255, 100, 100, 100); ret.Vertices[i].Alpha = 255; } #endregion return(ret); }
// DO NOT EDIT INSIDE THIS REGION !! CHANGES WILL BE LOST !! /// <summary> /// singular value decomposition /// </summary> /// <param name="X">matrix X. The elements of X will not be altered.</param> /// <param name="U">(return value) left singular vectors of X as columns of matrix U. /// If this parameter is set, it must be not null. It might be an empty array. On return /// it will be set to a physical array accordingly.</param> /// <param name="V">right singular vectors of X as rows of matrix V. /// If this parameter is set, it must be not null. It might be an empty array. On return /// it will be set to a physical array accordingly.</param> /// <param name="small">if true: return only first min(M,N) columns of U and S will be /// of size [min(M,N),min(M,N)]</param> /// <param name="discardFiniteTest">if true: the matrix given will not be checked for infinte or NaN values. If such elements /// are contained nevertheless, this may result in failing convergence or error. In worst case /// the function may hang inside the Lapack lib. Use with care! </param> /// <returns>singluar values as diagonal matrix of same size as X</returns> /// <remarks>the right singular vectors V will be returned as reference array.</remarks> public static ILArray <double> svd(ILArray <complex> X, ref ILArray <complex> U, ref ILArray <complex> V, bool small, bool discardFiniteTest) { if (!X.IsMatrix) { throw new ILArgumentSizeException("svd is defined for matrices only!"); } // early exit for small matrices if (X.Dimensions[1] < 4 && X.Dimensions[0] == X.Dimensions[1]) { switch (X.Dimensions[0]) { case 1: if (!Object.Equals(U, null)) { U = ( complex )1.0; } if (!Object.Equals(V, null)) { V = ( complex )1.0; } return(new ILArray <double> (ILMath.abs(X))); //case 2: // return -1; //case 3: // return -1; } } if (!discardFiniteTest && !all(all(isfinite(X)))) { throw new ILArgumentException("svd: input must have only finite elements!"); } if (Lapack == null) { throw new ILMathException("No Lapack package available."); } // parameter evaluation int M = X.Dimensions[0]; int N = X.Dimensions[1]; int minMN = (M < N) ? M : N; int LDU = M; int LDVT = N; int LDA = M; double [] dS = new double [minMN]; char jobz = (small) ? 'S' : 'A'; complex [] dU = null; complex [] dVT = null; int info = 0; if (!Object.Equals(U, null) || !Object.Equals(V, null)) { // need to return U and VT if (small) { dU = new complex [M * minMN]; dVT = new complex [N * minMN]; } else { dU = new complex [M * M]; dVT = new complex [N * N]; } } else { jobz = 'N'; } // must create copy of input ! complex [] dInput = new complex [X.m_data.Length]; System.Array.Copy(X.m_data, dInput, X.m_data.Length); Lapack.zgesdd(jobz, M, N, dInput, LDA, dS, dU, LDU, dVT, LDVT, ref info); if (info < 0) { throw new ILArgumentException("ILMath.svd: the " + (-info).ToString() + "th argument was invalid."); } if (info > 0) { throw new ILArgumentException("svd was not converging!"); } ILArray <double> ret = null; if (info == 0) { // success if (!Object.Equals(U, null) || !Object.Equals(V, null)) { if (small) { ret = ILArray <double> .zeros(minMN, minMN); } else { ret = ILArray <double> .zeros(M, N); } for (int i = 0; i < minMN; i++) { ret.SetValue(dS[i], i, i); } if (!Object.Equals(U, null)) { U = new ILArray <complex> (dU, M, dU.Length / M); } if (!Object.Equals(V, null)) { V = conj(new ILArray <complex> (dVT, N, dVT.Length / N).T); } } else { ret = new ILArray <double> (dS, minMN, 1); } } return(ret); }