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 + " мм.");
        }
示例#10
0
        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;
        }