public void Produce <T>(double delta_time, ICanvas <T> canvas, IPointDrawer point_drawer, IControlInformation information)
        {
            double x_delta_phase = delta_time / information.XPeriod;
            double y_delta_phase = delta_time / information.YPeriod;
            double old_x_phase;
            double old_y_phase;

            lock (locker)
            {
                old_x_phase    = saved_x_phase;
                old_y_phase    = saved_y_phase;
                saved_x_phase += x_delta_phase;
                saved_x_phase -= (int)saved_x_phase;
                saved_y_phase += y_delta_phase;
                saved_y_phase -= (int)saved_y_phase;
            }
            double x_phase_step = x_delta_phase / calculate_unit_number;
            double y_phase_step = y_delta_phase / calculate_unit_number;

            Parallel.For(0, calculate_unit_number, i =>
            {
                int start_count = i * calculate_unit_times;
                for (int j = start_count; j < start_count + calculate_unit_times; j++)
                {
                    double x_phase = old_x_phase + j * x_phase_step;
                    double y_phase = old_y_phase + j * y_phase_step;
                    x_phase       -= (int)x_phase;
                    y_phase       -= (int)y_phase;
                    information.Position(x_phase, y_phase, out PositionStruct position);
                    point_drawer.SetPoint(position);
                }
            });

            point_drawer.DrawAllPoint(canvas, graph_color, information.PointSize);
        }
        public void Produce <T>(double delta_time, ICanvas <T> canvas, IPointDrawer point_drawer, IControlInformation information)
        {
            double x_delta_phase = delta_time / information.XPeriod;
            double y_delta_phase = delta_time / information.YPeriod;
            double x_phase_step  = x_delta_phase / calculate_times;
            double y_phase_step  = y_delta_phase / calculate_times;

            x_phase_step -= (int)x_phase_step;
            y_phase_step -= (int)y_phase_step;

            for (int i = 0; i < calculate_times; i++)
            {
                x_phase += x_phase_step;
                y_phase += y_phase_step;
                if (x_phase >= 1)
                {
                    x_phase -= 1;
                }
                if (y_phase >= 1)
                {
                    y_phase -= 1;
                }
                information.Position(x_phase, y_phase, out PositionStruct position);
                point_drawer.SetPoint(position);
            }

            point_drawer.DrawAllPoint(canvas, graph_color, information.PointSize);
        }
        public void Produce <T>(double delta_time, ICanvas <T> canvas, IPointDrawer point_drawer, IControlInformation information)
        {
            double x_delta_phase = delta_time / information.XPeriod;
            double y_delta_phase = delta_time / information.YPeriod;
            double x_phase_step  = x_delta_phase / calculate_times;
            double y_phase_step  = y_delta_phase / calculate_times;
            double old_x_phase;
            double old_y_phase;
            Task   draw_old_ghosts;

            lock (locker)
            {
                PositionStruct[] old_ghosts = ghosts;

                draw_old_ghosts = new Task(() =>
                {
                    for (int i = 0; i < ghost_number; i++)
                    {
                        point_drawer.SetPoint(ghosts[i]);
                    }
                    point_drawer.DrawAllPoint(canvas, ghost_color, information.PointSize);
                });
                draw_old_ghosts.Start();

                ghosts         = new PositionStruct[ghost_number];
                old_x_phase    = saved_x_phase;
                old_y_phase    = saved_y_phase;
                saved_x_phase += x_delta_phase;
                saved_y_phase += y_delta_phase;
                saved_x_phase -= (int)saved_x_phase;
                saved_y_phase -= (int)saved_y_phase;

                int base_count = calculate_times - ghost_number;
                for (int i = 0; i < ghost_number; i++)
                {
                    int    total_count = i + base_count;
                    double x_phase     = old_x_phase + total_count * x_phase_step;
                    double y_phase     = old_y_phase + total_count * y_phase_step;
                    x_phase -= (int)x_phase;
                    y_phase -= (int)y_phase;
                    information.Position(x_phase, y_phase, out ghosts[i]);
                }
            }

            while (!draw_old_ghosts.IsCompleted)
            {
                Thread.Yield();
            }

            Task draw_new_ghosts = new Task(() =>
            {
                for (int i = 0; i < ghost_number; i++)
                {
                    point_drawer.SetPoint(ghosts[i]);
                }
            });

            draw_new_ghosts.Start();

            Parallel.For(0, calculate_times - ghost_number, i =>
            {
                double x_phase = old_x_phase + i * x_phase_step;
                double y_phase = old_y_phase + i * y_phase_step;
                x_phase       -= (int)x_phase;
                y_phase       -= (int)y_phase;
                information.Position(x_phase, y_phase, out PositionStruct position);
                point_drawer.SetPoint(position);
            });

            while (!draw_new_ghosts.IsCompleted)
            {
                Thread.Yield();
            }

            point_drawer.DrawAllPoint(canvas, graph_color, information.PointSize);
        }