void ShowOneCadr() { // показывает один кадр всего // по текущим параметрам WeatherCadr now = currentBlock[currentBlockCurrentCadr]; Bitmap cadr = new Bitmap((int)now.height, (int)now.weight); Graphics g = Graphics.FromImage(cadr); //// очистим //g.FillRectangle(new SolidBrush(Color.White), 0, 0, cadr.Width, cadr.Height); //pictureBox1.Image = cadr; // нарисуем землю for (int l = 0; l < now.Land.Count; l++) { g.FillEllipse(new SolidBrush(Color.DarkMagenta), (int)now.Land[l].X - (int)(now.Land[l].R), (int)now.Land[l].Y - (int)(now.Land[l].R), (int)now.Land[l].R * 2, (int)now.Land[l].R * 2); g.DrawString(Convert.ToString(now.Land[l].V), new Font("Arial", 10), new SolidBrush(Color.Aqua), (int)now.Land[l].X, (int)now.Land[l].Y); } // нарисуем циклоны for (int w = 0; w < now.Weather.Count; w++) { g.FillEllipse(new SolidBrush(Color.DarkGray), (int)now.Weather[w].X - (int)(now.Weather[w].R), (int)now.Weather[w].Y - (int)(now.Weather[w].R), (int)now.Weather[w].R * 2, (int)now.Weather[w].R * 2); g.DrawString(Convert.ToString(now.Weather[w].V), new Font("Arial", 10), new SolidBrush(Color.Black), (int)now.Weather[w].X, (int)now.Weather[w].Y); } pictureBox1.Image = cadr; }
public WeatherCadr CalculateTact() { int cadrPerLine = 24; //рассчитываем кадр исходя их текущих данных и возвращаем копию текущего состоянияю /* * рассчет: * * для каждого циклона: * по текущему времени вычисляем точку на траектории, на которой находится циклон сейчас. * двигаем циклон на шаг вперед. * по всем пересечениям ЭТОГО циклона с МЕСТНОСТЬЮ - обмениваем теплом циклон и местность. */ for (int i = 0; i < Weather.Count; i++) { // time это такты времени на которые мы двигаемся в рамках этого объекта калькулятора // один отрезок траектории - это день. такт времени путь будет час. 24 часа в дне. // сдвинуть в следующее положение нужно каждый циклон на 1/24 часть отрезка, на котором он сейчас находится. // на сами точки границ отрезков тоже проверяем. bool edit = false; // проверим не находимся ли мы сейчас внутри какогонить отрезка for (int p = 0; p < Weather[i].Path.Count - 1; p++) { // может мы в начале отрезка //if ((Weather[i].Path[p][0] == Weather[i].X) && (Weather[i].Path[p][1] == Weather[i].Y)) if (Math.Abs(Weather[i].Path[p][0] - Weather[i].X) < 1 && Math.Abs(Weather[i].Path[p][1] - Weather[i].Y) < 1) { // значит в начале этого отрезка // сдвинем циклон на 1/24 часть этого отрезка Weather[i].X = Weather[i].Path[p][0]; Weather[i].Y = Weather[i].Path[p][1]; double newX = Weather[i].Path[p][0] + (Weather[i].Path[p + 1][0] - Weather[i].Path[p][0]) / cadrPerLine; double newY = Weather[i].Path[p][1] + (Weather[i].Path[p + 1][1] - Weather[i].Path[p][1]) / cadrPerLine; Weather[i].X = newX; Weather[i].Y = newY; // сдвинули этот циклон // учтем изменение погоды MakeWeather(i); edit = true; break; } // может быть мы внутри этого отрезка int t = p + 1; if (t == Weather[i].Path.Count) { t = 0; } if (edit) { continue; } if (XYonSegment(Weather[i].X, Weather[i].Y, Weather[i].Path[p][0], Weather[i].Path[p][1], Weather[i].Path[t][0], Weather[i].Path[t][1])) { // значит внутри // можно узнать направление по каждой оси куда двигаемся по отрезку. и прибавить в эту сторону 1/24 часть длины отрезка! int x; if (Weather[i].Path[p][0] < Weather[i].Path[p + 1][0]) { x = 1; } else { x = -1; } int y; if (Weather[i].Path[p][1] < Weather[i].Path[p + 1][1]) { y = 1; } else { y = -1; } double newX = Math.Abs(Weather[i].Path[p][0] - Weather[i].Path[p + 1][0]) * x / cadrPerLine + Weather[i].X; double newY = Math.Abs(Weather[i].Path[p][1] - Weather[i].Path[p + 1][1]) * y / cadrPerLine + Weather[i].Y; Weather[i].X = newX; Weather[i].Y = newY; MakeWeather(i); } } } // сменили положение на один такт-час time++; WeatherCadr cadr = new WeatherCadr(Land, Weather, MapX, MapY); cadr.TIME = time; return(cadr); }
public List <WeatherCadr> GetWeatherFromCadr(WeatherCadr cadr, int time, IUserID user, string weather) { frames = 10; // порция кадров // нам нужно в память загрузить кадо WeatherCalculator wcalc = new WeatherCalculator(); wcalc.setTime = time; // добавим землю for (int i = 0; i < cadr.Land.Count; i++) { Land t = (Land)cadr.Land[i]; Land tmp = new Land(t.X, t.Y, t.R, t.V, t.C); wcalc.AddLand(tmp); } // добавим циклоны for (int i = 0; i < cadr.Weather.Count; i++) { Cyclone t = (Cyclone)cadr.Weather[i]; Cyclone tmp = new Cyclone(t.X, t.Y, t.R, t.V, t.C); wcalc.AddWeather(tmp); } // добавим траектории циклонов FileManagement.FileManager fm = Fabric.GetFileManager(); string[] weatherBuffer = fm.GetThisFile(user, weather);// буффер погоды string[] lines = weatherBuffer[0].Split(default(string[]), StringSplitOptions.RemoveEmptyEntries); wcalc.SetRect(Convert.ToDouble(lines[0]), Convert.ToDouble(lines[1])); int pos = 0; for (int i = 1; i < weatherBuffer.Length; i++) { string[] lines1 = weatherBuffer[i].Split(default(string[]), StringSplitOptions.RemoveEmptyEntries); if (lines1.Length == 0) // это условие отбросит строчки после пустой(траектории там для циклонов, если это погода) { pos = i; break; } } if (pos != 0) { pos++; for (int i = 0; i < weatherBuffer.Length - pos; i++) { if (weatherBuffer[i + pos].Length != 0) { List <double[]> add = new List <double[]>(); string[] tmp = weatherBuffer[i + pos].Split(default(string[]), StringSplitOptions.RemoveEmptyEntries); for (int t = 0; t < tmp.Length; t += 2) { add.Add(new double[2] { Convert.ToDouble(tmp[t]), Convert.ToDouble(tmp[t + 1]) }); } wcalc.AddWeatherPath(i, add); } } } // все заполнили List <WeatherCadr> answer = new List <WeatherCadr>(); for (int i = 0; i < frames; i++) { answer.Add(wcalc.CalculateTact());// рассчитали такт еще один и положили в ролик } return(answer); }
void ShowVideo() {// смотреть видео с указанного начального кадра в currentBlock // это значит мы можем внутри currentBlock начинать смотреть с любого кадра. WeatherCadr last = null; int i; if (currentBlockCurrentCadr != currentBlock.Count) {// это условие на то, что мы могли нажать кнопочку стоп в момент когда видео уже кончилось а новое не подгрузилось globaltime = currentBlock[currentBlockCurrentCadr].TIME; for (i = currentBlockCurrentCadr; i < currentBlock.Count; i++) { currentBlockCurrentCadr++; WeatherCadr now = currentBlock[i]; Bitmap cadr = new Bitmap((int)now.height, (int)now.weight); Graphics g = Graphics.FromImage(cadr); //// очистим //g.FillRectangle(new SolidBrush(Color.White), 0, 0, cadr.Width, cadr.Height); //pictureBox1.Image = cadr; // нарисуем землю for (int l = 0; l < now.Land.Count; l++) { g.FillEllipse(new SolidBrush(Color.DarkMagenta), (int)now.Land[l].X - (int)(now.Land[l].R), (int)now.Land[l].Y - (int)(now.Land[l].R), (int)now.Land[l].R * 2, (int)now.Land[l].R * 2); g.DrawString(Convert.ToString(now.Land[l].V), new Font("Arial", 10), new SolidBrush(Color.Aqua), (int)now.Land[l].X, (int)now.Land[l].Y); } // нарисуем циклоны for (int w = 0; w < now.Weather.Count; w++) { g.FillEllipse(new SolidBrush(Color.DarkGray), (int)now.Weather[w].X - (int)(now.Weather[w].R), (int)now.Weather[w].Y - (int)(now.Weather[w].R), (int)now.Weather[w].R * 2, (int)now.Weather[w].R * 2); g.DrawString(Convert.ToString(now.Weather[w].V), new Font("Arial", 10), new SolidBrush(Color.Black), (int)now.Weather[w].X, (int)now.Weather[w].Y); } pictureBox1.Image = cadr; ProgressSetTime(globaltime); globaltime++; System.Threading.Thread.Sleep(Convert.ToInt32(textBox1.Text)); if (i == currentBlock.Count - 1) { last = now; } } // если дошли до сюда - значит весь буффер просмотрели что был. нужен следующий // но если мы смотрим один из загруженных - и следующий тоже загружен - просто тот нужно взять // зарружать следующий нужно только если мы сейчас просмотрели последний загруженный блок if (posinold < oldBlocks.Count - 1) { // значит смотрим блок из старых, и следующий точно есть блок currentBlock = oldBlocks[posinold + 1]; posinold++; currentBlockStartTime = globaltime; currentBlockFrames = currentBlock.Count; currentBlockCurrentCadr = 0; revertShow(); } else if (last != null && globaltime < (int)((double)progress.Width / (double)progressStep)) { // значит нужна загрузка // запомним предыдущий блок bool f = false; for (int t = 0; t < oldBlocks.Count; t++) { if (oldBlocks[t][0].TIME == currentBlock[0].TIME) { f = true; } } if (!f) { oldBlocks.Add(currentBlock); } posinold++; globaltime--; currentBlock = wc.GetWeatherFromCadr(last, globaltime, user, weather); currentBlockStartTime = globaltime; // начальный момент времени для этого ролика currentBlockFrames = currentBlock.Count; // сколько кадров в этом ролике currentBlockCurrentCadr = 0; // какой кадр мы смотрим в данный момент revertShow(); } } }