/// <summary> /// retrieve given input set ordered with only distinct values after comparing through tolerance /// in this case result set contains only values from the input set (default) or rounding to given tol if maintain_original_values is false; /// if keep_ends true (default) min and max already exists at begin/end of returned sequence /// </summary> public static List <double> Thin(this IEnumerable <double> input, double tol, bool keep_ends = true, bool maintain_original_values = true) { var res = new List <double>(); var dcmp = new DoubleEqualityComparer(tol); if (maintain_original_values) { res = input.Distinct(dcmp).OrderBy(w => w).ToList(); } else { res = input.Select(w => w.MRound(tol)).Distinct(dcmp).OrderBy(w => w).ToList(); } var minmax = input.MinMax(); if (!res.First().EqualsTol(tol, minmax.min)) { res.Insert(0, minmax.min); } if (!res.Last().EqualsTol(tol, minmax.max)) { res.Add(minmax.max); } return(res); }
private static List <Storey> defStoreyNumberType(List <MarkSb> marksSB, int numberFirstFloor) { var storeysNumberType = new List <Storey>(); var comparerStorey = new DoubleEqualityComparer(Settings.Default.StoreyDefineDeviation); // 2000 // Панели этажные (без чердака и парапета) var panelsStoreyNumberType = marksSB.Where(sb => sb.StoreyTypePanel == EnumStorey.Number).SelectMany(sb => sb.MarksAR.SelectMany(ar => ar.Panels)).OrderBy(p => p.InsPt.Y); foreach (var panel in panelsStoreyNumberType) { Storey storey = storeysNumberType.Find(s => comparerStorey.Equals(s.Y, panel.InsPt.Y)); if (storey == null) { // Новый этаж storey = new Storey(panel.InsPt.Y); storeysNumberType.Add(storey); storeysNumberType.Sort((Storey s1, Storey s2) => s1.Y.CompareTo(s2.Y)); } panel.Storey = storey; } // Нумерация этажей int i = numberFirstFloor; var storeys = storeysNumberType.OrderBy(s => s.Y).ToList(); storeysNumberType.ForEach((s) => s.Number = i++); return(storeysNumberType); }
public void DoubleEqualityComparerTest() { var dcmp = new DoubleEqualityComparer(1e-4); var a = -0.00050000000000000044; var b = -0.000499999999999997; Assert.True(dcmp.Equals(a, b) && dcmp.GetHashCode(a) == dcmp.GetHashCode(b)); }
public void ToleranceTest_001() { var dbls = new [] { .1d, .2d, .21d, 1.2d, 1.21d }; var cmp = new DoubleEqualityComparer(1e-1); var q = dbls.Distinct(cmp); Assert.True(q.Count() == 3); }
/// <summary> /// create a set of subarc from this by splitting through given split points /// split point are not required to be on perimeter of the arc ( a center arc to point line will split ) /// generated subarcs will start from this arc angleFrom and contiguosly end to angleTo /// </summary> /// <param name="tol_len">arc length tolerance</param> /// <param name="_splitPts">point where split arc</param> /// <param name="validate_pts">if true split only for split points on arc perimeter</param> public IEnumerable <Arc3D> Split(double tol_len, IEnumerable <Vector3D> _splitPts, bool validate_pts = false) { var tol_rad = tol_len.RadTol(Radius); if (_splitPts == null || _splitPts.Count() == 0) { yield break; } IEnumerable <Vector3D> splitPts = _splitPts; if (validate_pts) { splitPts = _splitPts.Where(pt => Contains(tol_len, pt, onlyPerimeter: true)).ToList(); } var radCmp = new DoubleEqualityComparer(tol_rad); var hs_angles_rad = new HashSet <double>(radCmp); foreach (var splitPt in splitPts.Select(pt => PtAngle(tol_len, pt))) { if (PtAtAngle(splitPt).EqualsTol(tol_len, From) || PtAtAngle(splitPt).EqualsTol(tol_len, To)) { continue; } hs_angles_rad.Add(splitPt.NormalizeAngle2PI(tol_rad)); } var angles_rad = hs_angles_rad.OrderBy(w => w).ToList(); if (!hs_angles_rad.Contains(AngleStart)) { angles_rad.Insert(0, AngleStart); } if (!hs_angles_rad.Contains(AngleEnd)) { angles_rad.Add(AngleEnd); } for (int i = 0; i < angles_rad.Count - 1; ++i) { var arc = new Arc3D(tol_len, CS, Radius, angles_rad[i], angles_rad[i + 1]); yield return(arc); } }
public void ConvertEnds() { // Преобразование торцов фасада List <ConvertEndsFacade> convertsEnds = new List <ConvertEndsFacade>(); DoubleEqualityComparer comparer = new DoubleEqualityComparer(500); // Все вхождения блоков панелей с торцами слева var panelsWithLeftEndsByX = PanelsBtrExport.SelectMany(pBtr => pBtr.Panels). Where(pBlRef => pBlRef.PanelBtrExport.IdsEndsLeftEntity.Count > 0). GroupBy(pBlRef => pBlRef.Position.X, comparer); foreach (var itemLefEndsByY in panelsWithLeftEndsByX) { try { ConvertEndsFacade convertEndsFacade = new ConvertEndsFacade(itemLefEndsByY, true, this); convertEndsFacade.Convert(); convertsEnds.Add(convertEndsFacade); } catch (Exception ex) { Inspector.AddError($"Ошибка преобразования торцов панелей с координатой X точки вставки = {itemLefEndsByY.Key}. {ex}"); } } // Все вхождения блоков панелей с торцами справа var panelsWithRightEndsByX = PanelsBtrExport.SelectMany(pBtr => pBtr.Panels). Where(pBlRef => pBlRef.PanelBtrExport.IdsEndsRightEntity.Count > 0). GroupBy(pBlRef => pBlRef.Position.X, comparer); foreach (var itemRightEndsByY in panelsWithRightEndsByX) { try { ConvertEndsFacade convertEndsFacade = new ConvertEndsFacade(itemRightEndsByY, false, this); convertEndsFacade.Convert(); convertsEnds.Add(convertEndsFacade); } catch (Exception ex) { Inspector.AddError($"Ошибка преобразования торцов панелей с координатой X точки вставки = {itemRightEndsByY.Key}. {ex}"); } } // удаление торцов convertsEnds.ForEach(c => c.DeleteEnds()); }
public void ConvertEnds() { // Преобразование торцов фасада List<ConvertEndsFacade> convertsEnds = new List<ConvertEndsFacade>(); DoubleEqualityComparer comparer = new DoubleEqualityComparer(500); // Все вхождения блоков панелей с торцами слева var panelsWithLeftEndsByX = PanelsBtrExport.SelectMany(pBtr => pBtr.Panels). Where(pBlRef => pBlRef.PanelBtrExport.IdsEndsLeftEntity.Count > 0). GroupBy(pBlRef => pBlRef.Position.X, comparer); foreach (var itemLefEndsByY in panelsWithLeftEndsByX) { try { ConvertEndsFacade convertEndsFacade = new ConvertEndsFacade(itemLefEndsByY, true, this); convertEndsFacade.Convert(); convertsEnds.Add(convertEndsFacade); } catch (Exception ex) { Inspector.AddError($"Ошибка преобразования торцов панелей с координатой X точки вставки = {itemLefEndsByY.Key}. {ex}"); } } // Все вхождения блоков панелей с торцами справа var panelsWithRightEndsByX = PanelsBtrExport.SelectMany(pBtr => pBtr.Panels). Where(pBlRef => pBlRef.PanelBtrExport.IdsEndsRightEntity.Count > 0). GroupBy(pBlRef => pBlRef.Position.X, comparer); foreach (var itemRightEndsByY in panelsWithRightEndsByX) { try { ConvertEndsFacade convertEndsFacade = new ConvertEndsFacade(itemRightEndsByY, false, this); convertEndsFacade.Convert(); convertsEnds.Add(convertEndsFacade); } catch (Exception ex) { Inspector.AddError($"Ошибка преобразования торцов панелей с координатой X точки вставки = {itemRightEndsByY.Key}. {ex}"); } } // удаление торцов convertsEnds.ForEach(c => c.DeleteEnds()); }