private Cylinder[] CreateCylinders(Minutia minutia)
        {
            Cylinder3D value = new Cylinder3D();
            Cylinder3D mask  = new Cylinder3D();

            for (int i = 1; i <= BaseCuboid; i++)
            {
                for (int j = 1; j <= BaseCuboid; j++)
                {
                    if (IsValidPoint(GetPoint(i, j, minutia), minutia))
                    {
                        for (int k = 1; k <= HeightCuboid; k++)
                        {
                            mask.SetValue(i, j, k, 1);
                            value.SetValue(i, j, k, StepFunction(Sum(
                                                                     GetPoint(i, j, minutia),
                                                                     AngleHeight(k),
                                                                     GetNeighborhood(GetPoint(i, j, minutia), minutia),
                                                                     minutia
                                                                     )
                                                                 ));
                        }
                    }
                }
            }
            return(new[]
            {
                new Cylinder(value.Cylinder, minutia.Angle, Math.Sqrt(CylinderHelper.GetOneBitsCount(value.Cylinder))),
                new Cylinder(mask.Cylinder, minutia.Angle, Math.Sqrt(CylinderHelper.GetOneBitsCount(mask.Cylinder)))
            });
        }
        public Template CreateTemplate()
        {
            List <Cylinder> listCylinders = new List <Cylinder>();

            foreach (var middleMinutia in _minutiaeList)
            {
                int count = GetCountMinutia(middleMinutia);
                if (count >= MinNumberMinutiae)
                {
                    Cylinder[] cylinders = CreateCylinders(middleMinutia);
                    listCylinders.Add(cylinders[0]);
                    listCylinders.Add(cylinders[1]);
                }
            }
            uint maxCount = GetMaxCount(listCylinders);

            for (int i = 1; i < listCylinders.Count; i += 2)
            {
                if (CylinderHelper.GetOneBitsCount(listCylinders[i].Values) >= 0.75 * maxCount)
                {
                    continue;
                }
                listCylinders.RemoveAt(i--);
                listCylinders.RemoveAt(i--);
            }
            return(new Template(listCylinders.ToArray()));
        }
        private uint GetMaxCount(List <Cylinder> listCylinders)
        {
            uint maxCount = 0;

            for (int i = 1; i < listCylinders.Count; i += 2)
            {
                uint count = CylinderHelper.GetOneBitsCount(listCylinders[i].Values);
                maxCount = count > maxCount ? count : maxCount;
            }
            return(maxCount);
        }