public double CalculateValue(SlabModelImpl aSlabModel) { var topLine = aSlabModel.TopLines[aSlabModel.TopLines.Length/2]; var xPoints = new double[topLine.Length]; var yPoints = new double[topLine.Length]; for (var i = 0; i < topLine.Length; ++i) { xPoints[i] = topLine[i].Z; yPoints[i] = topLine[i].Y; } var saddlePoints = ConvexHull.Build(xPoints, yPoints, 1); var leftSaddlePoint = 0; var maxConcavity = double.MinValue; for (var i = 1; i < topLine.Length - 1; ++i) { if (i == saddlePoints[leftSaddlePoint + 1]) { maxConcavity = Math.Max(maxConcavity, 0); leftSaddlePoint++; } else { var distance = topLine[i].DistanceToLine( topLine[saddlePoints[leftSaddlePoint]], topLine[saddlePoints[leftSaddlePoint + 1]]); maxConcavity = Math.Max(maxConcavity, distance); } } return Math.Round(maxConcavity, 4, MidpointRounding.ToEven); }
public ISlabModel BuildSlabModel(bool aIsUseFilters = true) { if (container == null || container.IsEmpty()) { throw new ArgumentException("Контейнер не содержит данных для построения модели слитка."); } if (configuration == null) { throw new ArgumentException("Конфигурация не установлена."); } var slab = new SlabModelImpl(); MakePositionValues(); BuildSurfacePoints(slab); SplashFilter.Filter(slab); if (aIsUseFilters) { PickFilter.Filter(slab); } BuildCenters(slab); BuildLimits(slab); if (aIsUseFilters) { BumpFilter.Filter(slab); AverageFilter.Filter(slab); } return slab; }
public ISlabModel BuildSlabModel(bool aIsUseFilters) { if (container == null || container.IsEmpty()) { throw new ArgumentException("Контейнер не содержит данных для построения модели слитка."); } if (configuration == null) { throw new ArgumentException("Конфигурация не установлена."); } var slab = new SlabModelImpl(); MakePositionValues(); BuildTopLines(slab); BuildBottomLines(slab); BuildLeftLines(slab); BuildRightLines(slab); if (aIsUseFilters) { SplashFilter.Filter(slab); PickFilter.Filter(slab); BumpFilter.Filter(slab); AverageFilter.Filter(slab); //RotateFilter.Filter(slab); } BuildLimits(slab); return slab; }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } return Math.Round(aSlabModel.GetLengthLimit(), 4); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("TopCurvatureAlgorithm, CalculateValue: Модель слитка равна null."); } if (aSlabModel.CenterLine == null) { throw new ArgumentNullException("TopCurvatureAlgorithm, CalculateValue: Центральные точки равны null."); } if (aSlabModel.Diameters == null) { throw new ArgumentNullException("TopCurvatureAlgorithm, CalculateValue: Диаметры слитка равны null."); } if (aSlabModel.Diameters.Length != aSlabModel.CenterLine.Length) { throw new ArgumentNullException("TopCurvatureAlgorithm, CalculateValue: Количество центральных точек не равно количеству точек диаметра."); } var xpoints = new double[aSlabModel.CenterLine.Length]; var ypoints = new double[aSlabModel.CenterLine.Length]; var points3d = new Point3D[aSlabModel.CenterLine.Length]; for (var i = 0; i < aSlabModel.CenterLine.Length; ++i) { xpoints[i] = aSlabModel.CenterLine[i].Z; ypoints[i] = aSlabModel.CenterLine[i].Y + aSlabModel.Diameters[i] / 2.0; points3d[i] = new Point3D { X = xpoints[i], Y = ypoints[i], Z = 0 }; } // Строим выпуклую оболочку из имеющихся точек. var saddlePoints = ConvexHull.Build(xpoints, ypoints, 1); var leftSaddlePoint = 0; var maxCurvature = double.MinValue; for (var i = 1; i < points3d.Length - 1; ++i) { if (i == saddlePoints[leftSaddlePoint + 1]) { maxCurvature = Math.Max(maxCurvature, 0); leftSaddlePoint++; } else { var distance = points3d[i].DistanceToLine( points3d[saddlePoints[leftSaddlePoint]], points3d[saddlePoints[leftSaddlePoint + 1]]); maxCurvature = Math.Max(maxCurvature, distance); } } return Math.Round(maxCurvature, 4, MidpointRounding.ToEven); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } var indent = 30.0; // 3 см. // вычисляем середину слитка. var coordinateX = aSlabModel.GetLeftLimit() + 300; // отступ 30 см слева. var leftPoint = aSlabModel.GetTopSidePoint(coordinateX, indent); var rightPoint = aSlabModel.GetTopSidePoint(coordinateX, aSlabModel.GetLengthLimit() - indent); var middlePoint = aSlabModel.GetTopSidePoint(coordinateX, aSlabModel.GetLengthLimit()/2); return Math.Round(middlePoint.DistanceToLine(leftPoint, rightPoint), 4); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } // вычисляем середину слитка. var indent = 150.0; // 15 см. var coordinateY = (aSlabModel.GetBottomLimit() + aSlabModel.GetTopLimit())/2; var leftPoint = aSlabModel.GetRightSidePoint(coordinateY, indent); var rightPoint = aSlabModel.GetRightSidePoint(coordinateY, aSlabModel.GetLengthLimit() - indent); var middlePoint = aSlabModel.GetRightSidePoint(coordinateY, aSlabModel.GetLengthLimit()/2); return Math.Round(middlePoint.DistanceToLine(leftPoint, rightPoint), 4); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } var indent = 30.0; // 3 см. // вычисляем середину слитка. var coordinateY = 0; var leftPoint = aSlabModel.GetLeftSidePoint(coordinateY, indent); var rightPoint = aSlabModel.GetLeftSidePoint(coordinateY, aSlabModel.GetLengthLimit() - indent); var hypotenuse = leftPoint.DistanceToPoint(rightPoint); var angle = Math.Asin((leftPoint.X - rightPoint.X) / hypotenuse); return 180.0 * angle / Math.PI; }
private double frontIndent = 500; // отступ от торца слитка в мм. #endregion Fields #region Methods public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("FrontDiameterAlgorithm, CalculateValue: Модель слитка равна null."); } if (aSlabModel.Diameters == null || aSlabModel.Diameters.Length == 0) { throw new ArgumentNullException("FrontDiameterAlgorithm, CalculateValue: Диаметры отсутствуют."); } for (var i = 0; i < aSlabModel.CenterLine.Length; ++i) { if (aSlabModel.CenterLine[i].Z - aSlabModel.CenterLine[0].Z >= frontIndent) { return Math.Round(aSlabModel.Diameters[i] - 0.2, 4); } } throw new ArgumentException("FrontDiameterAlgorithm, CalculateValue: Нельзя вычислить диаметр с отступом в " + frontIndent + " мм."); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } // вычисляем середину слитка. var positionY = 0.5 * (aSlabModel.GetTopLimit() + aSlabModel.GetBottomLimit()); //var positionY = 0; // отступаем 10 см от торца слитка. var positionZ = 100; var leftPoint = aSlabModel.GetLeftSidePoint(positionY, positionZ); var rightPoint = aSlabModel.GetRightSidePoint(positionY, positionZ); var width = Math.Round(rightPoint.X - leftPoint.X, 4); return width; }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("aSlabModel"); } // вычисляем середину слитка. var positionX = 0.5 * (aSlabModel.GetRightLimit() + aSlabModel.GetLeftLimit()); //var positionX = 0; // отступаем 10 см от торца слитка. var positionZ = 100; var topPoint = aSlabModel.GetTopSidePoint(positionX, positionZ); var bottomPoint = aSlabModel.GetBottomSidePoint(positionX, positionZ); var height = Math.Round(topPoint.Y - bottomPoint.Y, 4, MidpointRounding.ToEven); return height; }
private double backIndent = 500; // отступ от торца слитка. #endregion Fields #region Methods public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("BackDiameterAlgorithm, CalculateValue: Модель слитка равна null."); } if (aSlabModel.Diameters == null || aSlabModel.Diameters.Length == 0) { throw new ArgumentNullException("BackDiameterAlgorithm, CalculateValue: Диаметры отсутствуют."); } var lastPoint = aSlabModel.CenterLine.Last(); for (var i = aSlabModel.CenterLine.Length - 1; i >= 0; --i) { if (lastPoint.Z - aSlabModel.CenterLine[i].Z >= backIndent) { return Math.Round(aSlabModel.Diameters[i] - 0.2, 4); } } throw new ArgumentException("BackDiameterAlgorithm, CalculateValue: Нельзя вычислить диаметр с отступом в " + backIndent + " мм."); }
public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("MiddleDiameterAlgorithm, CalculateValue: Модель слитка равна null."); } if (aSlabModel.Diameters == null || aSlabModel.Diameters.Length == 0) { throw new ArgumentNullException("MiddleDiameterAlgorithm, CalculateValue: Диаметры отсутствуют."); } var firstPoint = aSlabModel.CenterLine.First(); var lastPoint = aSlabModel.CenterLine.Last(); var middleDistance = firstPoint.Z + (lastPoint.Z - firstPoint.Z) / 2.0; for (var i = 0; i < aSlabModel.CenterLine.Length; ++i) { if (aSlabModel.CenterLine[i].Z >= middleDistance) { return Math.Round(aSlabModel.Diameters[i] - 0.2, 4); } } throw new ArgumentException("MiddleDiameterAlgorithm, CalculateValue: Не удалось найти среднюю точку."); }
private double frontIndent = 500; // отступ от торца слитка в мм. #endregion Fields #region Methods public double CalculateValue(SlabModelImpl aSlabModel) { if (aSlabModel == null) { throw new ArgumentNullException("FrontMiddleDiameterAlgorithm, CalculateValue: Модель слитка равна null."); } if (aSlabModel.Diameters == null || aSlabModel.Diameters.Length == 0) { throw new ArgumentNullException("FrontMiddleDiameterAlgorithm, CalculateValue: Диаметры отсутствуют."); } var firstPoint = aSlabModel.CenterLine.First(); var lastPoint = aSlabModel.CenterLine.Last(); var middleDistance = firstPoint.Z + (lastPoint.Z - firstPoint.Z) / 2.0; var controlDistance = middleDistance - (middleDistance - firstPoint.Z - frontIndent) / 2.0; for (var i = 0; i < aSlabModel.CenterLine.Length; ++i) { if (aSlabModel.CenterLine[i].Z >= controlDistance) { return Math.Round(aSlabModel.Diameters[i] - 0.2, 4); } } throw new ArgumentException("FrontMiddleDiameterAlgorithm, CalculateValue: Нельзя вычислить диаметр с отступом в " + frontIndent + " мм."); }
public double CalculateValue(SlabModelImpl aSlabModel) { var topLine = aSlabModel.TopLines[aSlabModel.TopLines.Length/2]; var xPoints = new double[topLine.Length]; var yPoints = new double[topLine.Length]; for (var i = 0; i < topLine.Length; ++i) { xPoints[i] = topLine[i].Z; yPoints[i] = topLine[i].Y; } var middlePoint = topLine.Length/2; var saddlePoints = ConvexHull.Build(xPoints, yPoints, 1); for (var i = 0; i < saddlePoints.Length - 1; ++i) { if (middlePoint >= saddlePoints[i] && middlePoint <= saddlePoints[i + 1]) { var leftPoint = topLine[saddlePoints[i]]; var rightPoint = topLine[saddlePoints[i + 1]]; var distance = topLine[middlePoint].DistanceToLine(leftPoint, rightPoint); return Math.Round(distance, 4, MidpointRounding.ToEven); } } return 0; }
private void BuildLimits(SlabModelImpl aSlab) { aSlab.TopLimit = double.MinValue; aSlab.BottomLimit = double.MaxValue; aSlab.LeftLimit = double.MaxValue; aSlab.RightLimit = double.MinValue; aSlab.LengthLimit = double.MinValue; var sensorCount = aSlab.TopLines.Length; for (var i = 0; i < sensorCount; ++i) { var values = aSlab.TopLines[i]; for (var j = 0; j < values.Length; ++j) { aSlab.TopLimit = Math.Max(aSlab.TopLimit, values[j].Y); } aSlab.LengthLimit = Math.Max(aSlab.LengthLimit, values[values.Length - 1].Z - values[0].Z); } sensorCount = aSlab.BottomLines.Length; for (var i = 0; i < sensorCount; ++i) { var values = aSlab.BottomLines[i]; for (var j = 0; j < values.Length; ++j) { aSlab.BottomLimit = Math.Min(aSlab.BottomLimit, values[j].Y); } } sensorCount = aSlab.LeftLines.Length; for (var i = 0; i < sensorCount; ++i) { var values = aSlab.LeftLines[i]; for (var j = 0; j < values.Length; ++j) { aSlab.LeftLimit = Math.Min(aSlab.LeftLimit, values[j].X); } } sensorCount = aSlab.RightLines.Length; for (var i = 0; i < sensorCount; ++i) { var values = aSlab.RightLines[i]; for (var j = 0; j < values.Length; ++j) { aSlab.RightLimit = Math.Max(aSlab.RightLimit, values[j].X); } } }
private void BuildSurfacePoints(SlabModelImpl aModel) { // сначала создадим массивы точек на поверхности слитка. var sensors = GetProximitySensors(); for (var i = 0; i < sensors.Count; ++i) { var sensor = sensors[i]; var sensorValues = container.GetSensorValuesBySensorId(sensor.GetId()); RemoveFilteredValues(ref sensorValues); var sensorLine = BuildLineValues( sensor, positionValues, sensorValues, sensor.GetShift(), calibrator.GetCalibratedValue(sensor.GetId()) / 2.0); MoveToZeroOnZ(sensorLine); switch (sensor.GetSensorSide()) { case SensorSide.TOP: aModel.TopSensorLine = sensorLine; break; case SensorSide.BOTTOM: aModel.BottomSensorLine = sensorLine; break; case SensorSide.LEFT: aModel.LeftSensorLine = sensorLine; break; case SensorSide.RIGHT: aModel.RightSensorLine = sensorLine; break; } } }
private void BuildLimits(SlabModelImpl aModel) { aModel.LengthLimit = aModel.CenterLine[aModel.CenterLine.Length - 1].Z; }
/// <summary> /// Строит линию центров слитка. /// </summary> /// <param name="aModel"></param> private void BuildCenters(SlabModelImpl aModel) { // теперь по 3-м точкам будем строить описанную окружность и вычислять ее центр и диаметр. var centers = new List<Point3D>(); var diameters = new List<double>(); var lines = new Point3D[3][]; lines[0] = aModel.TopSensorLine; lines[1] = aModel.BottomSensorLine; lines[2] = aModel.LeftSensorLine; var indexes = new int[3] { 0, 0, 0 }; MoveToOnePlainZ(ref indexes, lines); // двигает границы массивов до тех пор, пока все точки не станут в одной плоскости. var pointsCount = int.MaxValue; for (var i = 0; i < 3; ++i) { pointsCount = Math.Min(pointsCount, lines[i].Length - indexes[i]); } for (var i = 0; i < pointsCount; ++i) { var a = indexes[0]; var b = indexes[1]; var c = indexes[2]; var center = CalcCircleCenter(lines[0][a], lines[1][b], lines[2][c]); var diameter = CalcCircleDiameter(lines[0][a], lines[1][b], lines[2][c]); centers.Add(center); diameters.Add(diameter); indexes[0]++; indexes[1]++; indexes[2]++; } aModel.CenterLine = centers.ToArray(); aModel.Diameters = diameters.ToArray(); }
private void BuildTopLines(SlabModelImpl aSlab) { var sensors = GetProximitySensors(SensorSide.TOP); // Сортируем по увеличению отступа - слева на право. sensors.Sort((a, b) => a.GetShift() < b.GetShift() ? 1 : 0); aSlab.TopLines = new Point3D[sensors.Count][]; for (var i = 0; i < sensors.Count; ++i) { var sensor = sensors[i]; var sensorValues = container.GetSensorValuesBySensorId(sensor.GetId()); RemoveFilteredValues(ref sensorValues); aSlab.TopLines[i] = BuildTopValues( positionValues, sensorValues, sensor.GetShift(), calibrator.GetCalibratedValue(sensor.GetId()) / 2.0); MoveToZeroOnZ(aSlab.TopLines[i]); } }
private ISlabModel BuildSlabModel() { var slab = new SlabModelImpl(); slab.TopLimit = 50*10; slab.BottomLimit = -50*10; slab.LeftLimit = -50*10; slab.RightLimit = 50*10; slab.LengthLimit = 1000; slab.TopLines = new Point3D[3][]; for (var i = 0; i < 3; ++i) { slab.TopLines[i] = new Point3D[1000]; for (var j = 0; j < 1000; ++j) { slab.TopLines[i][j] = new Point3D { X = -20*10 + i * (20 * 10), Y = 50 * 10, Z = j }; } } slab.BottomLines = new Point3D[3][]; for (var i = 0; i < 3; ++i) { slab.BottomLines[i] = new Point3D[1000]; for (var j = 0; j < 1000; ++j) { slab.BottomLines[i][j] = new Point3D { X = -20 * 10 + i * (20 * 10), Y = -50 * 10, Z = j }; } } slab.LeftLines = new Point3D[3][]; for (var i = 0; i < 3; ++i) { slab.LeftLines[i] = new Point3D[1000]; for (var j = 0; j < 1000; ++j) { slab.LeftLines[i][j] = new Point3D { X = -50 * 10, Y = -20 * 10 + i * (20 * 10), Z = j }; } } slab.RightLines = new Point3D[3][]; for (var i = 0; i < 3; ++i) { slab.RightLines[i] = new Point3D[1000]; for (var j = 0; j < 1000; ++j) { slab.RightLines[i][j] = new Point3D { X = 50 * 10, Y = -20 * 10 + i * (20 * 10), Z = j }; } } return slab; }