private static void FilterLeftView(ref SlabPoint[] aLine)
        {
            if (aLine == null) {
                return;
            }

            var startDeletetIndex = int.MinValue;
            for (var i = MAX_POINT_COUNT; i > 0 && i < aLine.Length; --i) {
                if (IsSplash(aLine[i - 1].Z, aLine[i - 1].Y, aLine[i].Z, aLine[i].Y)) {
                    startDeletetIndex = i;
                    break;
                }
            }

            var endDeletetIndex = int.MaxValue;
            for (var i = aLine.Length - MAX_POINT_COUNT; i > 0 && i < aLine.Length; ++i) {
                if (IsSplash(aLine[i - 1].Z, aLine[i - 1].Y, aLine[i].Z, aLine[i].Y)) {
                    endDeletetIndex = i - 1;
                    break;
                }
            }

            if (startDeletetIndex != int.MinValue || endDeletetIndex != int.MaxValue) {
                var points = new List<SlabPoint>();
                for (var i = 0; i < aLine.Length; ++i) {
                    if (i >= startDeletetIndex && i <= endDeletetIndex) {
                        points.Add(aLine[i]);
                    }
                }

                aLine = points.ToArray();
            }
        }
        private static void FilterLine(SlabPoint[] aLine, int[] aSegments)
        {
            if (aLine == null) {
                return;
            }

            for (var s = 0; s < aSegments.Length/2; ++s) {
                var from = aSegments[s*2];
                var to = aSegments[s*2 + 1];
                if (to - from >= WINDOW_SIZE*2 + 1) {
                    var averages = new double[to - from + 1];
                    var index = 0;
                    for (var i = from; i <= to; ++i) {
                        var summed = 0.0;
                        var count = 0;
                        for (var j = i - WINDOW_SIZE; j <= i + WINDOW_SIZE; ++j) {
                            if (j >= 0 && j < aLine.Length && j >= from && j <= to) {
                                summed += aLine[j].Y;
                                count++;
                            }
                        }
                        averages[index++] = summed / count;
                    }

                    index = 0;
                    for (var i = from; i <= to; ++i) {
                        aLine[i].Y = averages[index++];
                    }
                }
            }
        }
        private void DrawCallout()
        {
            var p0 = new SlabPoint();
            var backIndent = 150; // отступ.
            var pointIndex = -1;
            var lastPoint = SlabModel.CenterLine.Last();
            for (var i = SlabModel.CenterLine.Length - 1; i >= 0; --i) {
                if (lastPoint.Z - SlabModel.CenterLine[i].Z >= backIndent) {
                    pointIndex = i;
                    p0.X = SlabModel.CenterLine[i].X;
                    p0.Y = SlabModel.CenterLine[i].Y;
                    p0.Z = SlabModel.CenterLine[i].Z;
                    break;
                }
            }

            p0.Y += SlabModel.Diameters[pointIndex] / 2.0;

            var p1 = new SlabPoint();
            p1.X = p0.X + SlabModel.Diameters[pointIndex] / 2.0 + 500;
            p1.Y = p0.Y;
            p1.Z = p0.Z;

            SetCalloutLineType();
            Gl.glBegin(Gl.GL_LINES);
            {
                Gl.glVertex3d(p0.X, p0.Y, p0.Z);
                Gl.glVertex3d(p1.X, p1.Y, p1.Z);
                Gl.glVertex3d(p0.X, p0.Y - SlabModel.Diameters[pointIndex], p0.Z);
                Gl.glVertex3d(p1.X, p1.Y - SlabModel.Diameters[pointIndex], p1.Z);
                Gl.glVertex3d(p1.X - 70, p1.Y, p1.Z);
                Gl.glVertex3d(p1.X - 70, p1.Y - SlabModel.Diameters[pointIndex], p1.Z);
            }
            Gl.glEnd();
        }
 private void DrawSphere(bool aIsSmoothEnable)
 {
     Gl.glPushMatrix();
     var p0 = new SlabPoint();
     var frontIndent = 150; // отступ.
     var pointIndex = -1;
     for (var i = 0; i < SlabModel.CenterLine.Length; ++i) {
         if (SlabModel.CenterLine[i].Z - SlabModel.CenterLine[0].Z >= frontIndent) {
             pointIndex = i;
             p0.X = SlabModel.CenterLine[i].X;
             p0.Y = SlabModel.CenterLine[i].Y;
             p0.Z = SlabModel.CenterLine[i].Z;
             break;
         }
     }
     var translateX = p0.X + SlabModel.Diameters[pointIndex]/2.0 + 520;
     var translateY = p0.Y;
     var translateZ = p0.Z;
     Gl.glTranslated(translateX, translateY, translateZ);
     Gl.glColor3d(Convert.ToDouble(Color.R) / 255,
                  Convert.ToDouble(Color.G) / 255,
                  Convert.ToDouble(Color.B) / 255);
     if (aIsSmoothEnable) {
         Gl.glDisable(Gl.GL_MULTISAMPLE_ARB);
         Gl.glDisable(Gl.GL_LINE_SMOOTH);
         Gl.glDisable(Gl.GL_BLEND);
     }
     Glut.glutSolidSphere(SphereSize, 15, 15);
     if (aIsSmoothEnable) {
         Gl.glEnable(Gl.GL_MULTISAMPLE_ARB);
         Gl.glEnable(Gl.GL_LINE_SMOOTH);
         Gl.glEnable(Gl.GL_BLEND);
     }
     Gl.glPopMatrix();
 }
        private static void FilterLeftView(SlabPoint[] aLine)
        {
            if (aLine == null) {
                return;
            }

            for (var i = 0; i < aLine.Length - 2; ++i) {
                var a = aLine[i];
                var b = aLine[i + 1];
                var c = aLine[i + 2];
                if (IsPick(a.Y, b.Y, c.Y)) {
                    b.Y = (a.Y + c.Y) / 2;                    
                }
            }
        }
        private static void FilterTopView(SlabPoint[] aLine)
        {
            if (aLine == null) {
                return;
            }

            for (var i = 0; i < aLine.Length - 2; ++i) {
                var a = aLine[i];
                var b = aLine[i + 1];
                var c = aLine[i + 2];
                if (IsPick(a.X, b.X, c.X)) {
                    b.X = (a.X + c.X) / 2;                    
                }
            }
        }
 private void DrawCallout()
 {
     var p0 = new SlabPoint();
     var p1 = new SlabPoint();
     p0.X = (SlabModel.LeftLines[0].First().X + SlabModel.RightLines[0][0].X) / 2;
     p0.Y = SlabModel.TopLines[0].First().Y + 20;
     p0.Z = SlabModel.TopLines[0].First().Z;
     p1.X = p0.X;
     p1.Y = p0.Y;
     p1.Z = SlabModel.TopLines[0].Last().Z;
     SetCalloutLineType();
     Gl.glBegin(Gl.GL_LINES);
     {
         Gl.glVertex3d(p0.X, p0.Y, p0.Z);
         Gl.glVertex3d(p1.X, p1.Y, p1.Z);
     }
     Gl.glEnd();
 }
        private static int[] FindSegments(SlabPoint[] aLine)
        {
            var segments = new List<int>();
            for (var i = 0; i < aLine.Length; ++i) {
                var difLeft = false;
                var difRight = false;
                if (i == 0 || Math.Abs(DxDivDy(aLine[i], aLine[i - 1])) >= 1) {
                    difLeft = true;
                }

                if (i == aLine.Length - 1 || Math.Abs(DxDivDy(aLine[i], aLine[i + 1])) >= 1) {
                    difRight = true;
                }

                if (difRight ^ difLeft) {
                    segments.Add(i);
                }
            }

            return segments.ToArray();
        }
 private void DrawCallout()
 {
     var p0 = new SlabPoint();
     var p1 = new SlabPoint();
     p0.X = SlabModel.RightLines[0].Last().X;
     p0.Y = SlabModel.BottomLines[0].Last().Y;
     p0.Z = SlabModel.RightLines[0].Last().Z;
     p1.X = p0.X;
     p1.Y = p0.Y;
     p1.Z = p0.Z + 500;
     SetCalloutLineType();
     Gl.glBegin(Gl.GL_LINES);
     {
         Gl.glVertex3d(p0.X, p0.Y, p0.Z);
         Gl.glVertex3d(p1.X, p1.Y, p1.Z);
         Gl.glVertex3d(SlabModel.LeftLines[0].Last().X, p0.Y, p0.Z);
         Gl.glVertex3d(SlabModel.LeftLines[0].Last().X, p0.Y, p1.Z);
         Gl.glVertex3d(p1.X, p1.Y, p1.Z - 70);
         Gl.glVertex3d(SlabModel.LeftLines[0].Last().X, p1.Y, p1.Z - 70);
     }
     Gl.glEnd();
 }
 private void DrawCallout()
 {
     var p0 = new SlabPoint();
     var p1 = new SlabPoint();
     p0.X = SlabModel.CenterLine.First().X;
     p0.Y = SlabModel.CenterLine.First().Y;
     p0.Z = SlabModel.CenterLine.First().Z;
     p1.X = p0.X - SlabModel.Diameters[0]/2.0 - 500;
     p1.Y = p0.Y;
     p1.Z = p0.Z;
     SetCalloutLineType();
     Gl.glBegin(Gl.GL_LINES);
     {
         Gl.glVertex3d(p0.X, p0.Y, p0.Z);
         Gl.glVertex3d(p1.X, p1.Y, p1.Z);
         Gl.glVertex3d(p0.X, p0.Y, SlabModel.CenterLine.Last().Z);
         Gl.glVertex3d(p1.X, p1.Y, SlabModel.CenterLine.Last().Z);
         Gl.glVertex3d(p1.X + 70, p1.Y, p1.Z);
         Gl.glVertex3d(p1.X + 70, p1.Y, SlabModel.CenterLine.Last().Z);
     }
     Gl.glEnd();
 }
 private static double DxDivDy(SlabPoint aPointA, SlabPoint aPointB)
 {
     return (aPointA.Y - aPointB.Y)/(aPointA.Z - aPointB.Z);
 }
 private void AddCircle(SlabPoint aCenter, double aRadius)
 {
     var pointsCount = 70;
     for (var i = 0; i < pointsCount; ++i) {
         var angle = 2.0 * Math.PI * i / pointsCount;
         Gl.glVertex3d(aCenter.X + aRadius * Math.Cos(angle), aCenter.Y + aRadius * Math.Sin(angle), aCenter.Z);
     }
 }
        private TuplePoints GetTopSectionPoints(SlabPoint[] aLine, double aMultiplicator)
        {
            var xPoints = new List<double>();
            var yPoints = new List<double>();
            if (aLine != null) {
                for (var i = 0; i < aLine.Length; ++i) {
                    xPoints.Add(aLine[i].Z);
                    yPoints.Add(aLine[i].X + aMultiplicator * slabModel.Diameters[i] / 2.0);
                }
            }

            return new TuplePoints {
                X = xPoints.ToArray(),
                Y = yPoints.ToArray()
            };
        }
        private TuplePoints GetTopSectionPoints(SlabPoint[] aLine)
        {
            var xPoints = new List<double>();
            var yPoints = new List<double>();
            if (aLine != null) {
                for (var i = 0; i < aLine.Length; ++i) {
                    xPoints.Add(aLine[i].Z);
                    yPoints.Add(aLine[i].X);
                }
            }

            return new TuplePoints {
                X = xPoints.ToArray(),
                Y = yPoints.ToArray()
            };
        }
        public SlabModel3D ToSlabModel()
        {
            var model = new SlabModel3D();
            model.TopLines = new SlabPoint[TopLines.Length][];
            model.BottomLines = new SlabPoint[BottomLines.Length][];
            model.LeftLines = new SlabPoint[LeftLines.Length][];
            model.RightLines = new SlabPoint[RightLines.Length][];
            for (var i = 0; i < TopLines.Length; ++i) {
                var line = new List<SlabPoint>();
                for (var j = 0; j < TopLines[i].Length; ++j) {
                    var linePoint = TopLines[i][j];
                    var point = new SlabPoint {
                        X = linePoint.X,
                        Y = linePoint.Y,
                        Z = linePoint.Z
                    };
                    line.Add(point);
                }
                model.TopLines[i] = line.ToArray();
            }

            for (var i = 0; i < BottomLines.Length; ++i) {
                var line = new List<SlabPoint>();
                for (var j = 0; j < BottomLines[i].Length; ++j) {
                    var linePoint = BottomLines[i][j];
                    var point = new SlabPoint {
                        X = linePoint.X,
                        Y = linePoint.Y,
                        Z = linePoint.Z
                    };
                    line.Add(point);
                }
                model.BottomLines[i] = line.ToArray();
            }

            for (var i = 0; i < LeftLines.Length; ++i) {
                var line = new List<SlabPoint>();
                for (var j = 0; j < LeftLines[i].Length; ++j) {
                    var linePoint = LeftLines[i][j];
                    var point = new SlabPoint {
                        X = linePoint.X,
                        Y = linePoint.Y,
                        Z = linePoint.Z
                    };
                    line.Add(point);
                }
                model.LeftLines[i] = line.ToArray();
            }

            for (var i = 0; i < RightLines.Length; ++i) {
                var line = new List<SlabPoint>();
                for (var j = 0; j < RightLines[i].Length; ++j) {
                    var linePoint = RightLines[i][j];
                    var point = new SlabPoint {
                        X = linePoint.X,
                        Y = linePoint.Y,
                        Z = linePoint.Z
                    };
                    line.Add(point);
                }
                model.RightLines[i] = line.ToArray();
            }

            return model;
        }
        private SlabPoint[] BuildSensorLine(Point3D[] aSensorLine)
        {
            var sensorLine = new SlabPoint[aSensorLine.Length];
            for (var i = 0; i < aSensorLine.Length; ++i) {
                sensorLine[i] = new SlabPoint {
                    X = aSensorLine[i].X,
                    Y = aSensorLine[i].Y,
                    Z = aSensorLine[i].Z,
                };
            }

            return sensorLine;
        }