Exemplo n.º 1
0
        //Sistema de dibujo
        //Objetivo: Dibujar los planos en todos los lienzos.

        private void dibujar()
        {
            //Cronometro de progress bar
            Stopwatch cropro = new Stopwatch();

            cropro.Start();



            Random azar = new Random();
            //Variable para busqueda de origen
            int x_ori = Convert.ToInt32(ui_min_ancho_casa.Value) * 100, y_ori = Convert.ToInt32(ui_min_alto_casa.Value) * 100;

            List <Info_forma>        lista_casas = new List <Info_forma>();
            List <Composicion_calle> lista_comp_calles = new List <Composicion_calle>();
            List <Point>             lista_puntos_calles = new List <Point>();

            //Subsitema #1: calculo de area ciudad

            //Calculo del margen del area de dibujo, para que las formas no sobresalgan
            int margen_ancho = Convert.ToInt32(ui_max_ancho_casa.Value) * 100;
            int margen_alto  = Convert.ToInt32(ui_max_alto_casa.Value) * 100;

            //-------

            int ancho_lienzo = 0, alto_lienzo = 0, area = 0;

            List <int> anchos = new List <int>();
            List <int> altos  = new List <int>();

            for (int i = 0; i < ui_cantidad_casas.Value; i++)
            {
                anchos.Add(azar.Next(Convert.ToInt32(ui_min_ancho_casa.Value), Convert.ToInt32(ui_max_ancho_casa.Value) + 1));
                altos.Add(azar.Next(Convert.ToInt32(ui_min_alto_casa.Value), Convert.ToInt32(ui_max_alto_casa.Value) + 1));
            }
            for (int x = 0; x < ui_cantidad_casas.Value; x++)
            {
                int precalculo = (anchos[x] * altos[x]) * 100;
                area = area + precalculo;
            }

            ancho_lienzo = alto_lienzo = (int)Math.Sqrt(area) * 10;

            float por_ancho = (float)(ancho_lienzo * (Convert.ToInt32(ui_porcentaje_sin_casas.Value) * 0.01));

            ancho_lienzo = (int)(ancho_lienzo + por_ancho);
            ancho_lienzo = ancho_lienzo + margen_ancho;

            float por_alto = (float)(alto_lienzo * (Convert.ToInt32(ui_porcentaje_sin_casas.Value) * 0.01));

            alto_lienzo = (int)(alto_lienzo + por_alto);
            alto_lienzo = alto_lienzo + margen_alto;

            //Mostrar area de ciudad

            ui_label_m2.Text = Convert.ToString((ancho_lienzo / 100 * alto_lienzo / 100));

            //Llamada a la función que crea los lienzos

            crear_pages_area_casas(ancho_lienzo, alto_lienzo);

            //Pintado en el fondo del picture box

            PictureBox primer_nivel = (PictureBox)TabControl.TabPages[0].Controls.Find("Planta 0", true)[0];
            Graphics   fondo        = Graphics.FromImage(primer_nivel.Image);
            Brush      brocha_fondo = new SolidBrush(Color.DarkGreen);

            fondo.FillRectangle(brocha_fondo, new Rectangle(new Point(0, 0), new Size(ancho_lienzo, alto_lienzo)));


            //Subsistema # 2 creación de calles

            if (ui_calle_cuadricula.Checked == true)
            {
                //Se dibujan las veredas (Calle base)
                int dist_entre_cll = Convert.ToInt32(ui_espacio_calles.Value) * 100;

                for (int y = dist_entre_cll; y < alto_lienzo; y += dist_entre_cll)
                {
                    int ancho_calle  = azar.Next(Convert.ToInt32(ui_min_ancho_calle.Value), Convert.ToInt32(ui_max_ancho_calle.Value));
                    int ancho_vereda = azar.Next(Convert.ToInt32(ui_min_ancho_ver.Value), Convert.ToInt32(ui_max_ancho_ver.Value));
                    lista_comp_calles.Add(new Composicion_calle(new Pen(Color.White, (ancho_calle + ancho_vereda) * 100), new Pen(Color.FromArgb(88, 88, 88), ancho_calle * 100), new Point(0, y), new Point(ancho_lienzo, y)));
                }
                for (int x = dist_entre_cll; x < ancho_lienzo; x += dist_entre_cll)
                {
                    int ancho_calle  = azar.Next(Convert.ToInt32(ui_min_ancho_calle.Value), Convert.ToInt32(ui_max_ancho_calle.Value));
                    int ancho_vereda = azar.Next(Convert.ToInt32(ui_min_ancho_ver.Value), Convert.ToInt32(ui_max_ancho_ver.Value));
                    lista_comp_calles.Add(new Composicion_calle(new Pen(Color.White, (ancho_calle + ancho_vereda) * 100), new Pen(Color.FromArgb(88, 88, 88), ancho_calle * 100), new Point(x, 0), new Point(x, alto_lienzo)));
                }
                for (int i = 0; i < lista_comp_calles.Count; i++)
                {
                    fondo.DrawLine(lista_comp_calles[i].calle_base, lista_comp_calles[i].inicio, lista_comp_calles[i].fin);
                    primer_nivel.Refresh();
                }

                //Subsistema # 2.1 Deteccion de pixeles blancos "Pixeles de linea base"
                lista_puntos_calles = Herramienta.obtener_coor_pixel_blancos((Bitmap)primer_nivel.Image);

                //Se dibujan las calles
                for (int i = 0; i < lista_comp_calles.Count; i++)
                {
                    fondo.DrawLine(lista_comp_calles[i].calle, lista_comp_calles[i].inicio, lista_comp_calles[i].fin);
                    primer_nivel.Refresh();
                }
            }
            else if (ui_calle_incompleta.Checked == true)
            {
                //Se dibujan las veredas (Calle base)
                int dist_entre_cll = Convert.ToInt32(ui_espacio_calles.Value) * 100;
                int longitud_x     = ancho_lienzo / dist_entre_cll;
                int longitud_y     = alto_lienzo / dist_entre_cll;
                //Pen dash_street = new Pen(Color.Yellow,20);
                //dash_street.DashStyle = DashStyle.Dash;

                for (int y = dist_entre_cll; y < alto_lienzo; y += dist_entre_cll)
                {
                    int ancho_calle  = azar.Next(Convert.ToInt32(ui_min_ancho_calle.Value), Convert.ToInt32(ui_max_ancho_calle.Value));
                    int ancho_vereda = azar.Next(Convert.ToInt32(ui_min_ancho_ver.Value), Convert.ToInt32(ui_max_ancho_ver.Value));
                    lista_comp_calles.Add(new Composicion_calle(new Pen(Color.White, (ancho_calle + ancho_vereda) * 100), new Pen(Color.FromArgb(88, 88, 88), ancho_calle * 100), new Point(azar.Next(0, longitud_x - 1) * dist_entre_cll, y), new Point(azar.Next(3, longitud_x + 2) * dist_entre_cll, y)));
                }
                for (int x = dist_entre_cll; x < ancho_lienzo; x += dist_entre_cll)
                {
                    int ancho_calle  = azar.Next(Convert.ToInt32(ui_min_ancho_calle.Value), Convert.ToInt32(ui_max_ancho_calle.Value));
                    int ancho_vereda = azar.Next(Convert.ToInt32(ui_min_ancho_ver.Value), Convert.ToInt32(ui_max_ancho_ver.Value));
                    lista_comp_calles.Add(new Composicion_calle(new Pen(Color.White, (ancho_calle + ancho_vereda) * 100), new Pen(Color.FromArgb(88, 88, 88), ancho_calle * 100), new Point(x, azar.Next(0, longitud_y - 1)), new Point(x, azar.Next(3, longitud_y + 2) * dist_entre_cll)));
                }
                for (int i = 0; i < lista_comp_calles.Count; i++)
                {
                    fondo.DrawLine(lista_comp_calles[i].calle_base, lista_comp_calles[i].inicio, lista_comp_calles[i].fin);
                    primer_nivel.Refresh();
                }

                //Subsistema # 2.1 Deteccion de pixeles blancos "Pixeles de linea base"
                lista_puntos_calles = Herramienta.obtener_coor_pixel_blancos((Bitmap)primer_nivel.Image);

                //Se dibujan las calles
                for (int i = 0; i < lista_comp_calles.Count; i++)
                {
                    fondo.DrawLine(lista_comp_calles[i].calle, lista_comp_calles[i].inicio, lista_comp_calles[i].fin);
                    //fondo.DrawLine(dash_street, lista_comp_calles[i].inicio, lista_comp_calles[i].fin);
                    primer_nivel.Refresh();
                }
            }
            else if (ui_calle_curvilineal.Checked == true)
            {
            }
            else if (ui_calle_callejones.Checked == true)
            {
            }



            //MessageBox.Show(Convert.ToString(lista_puntos_calles.Count));


            //Subsistema # 3 de recoleccion de datos: casas

            Stopwatch cronometro = new Stopwatch();

            cronometro.Start();



            for (int ubicacion_datos = 0; ubicacion_datos < ui_cantidad_casas.Value; ubicacion_datos++)
            {
                //Actualización del progress bar #1

                barra.Value = (int)cropro.Elapsed.TotalSeconds;



                if (cronometro.ElapsedMilliseconds >= Convert.ToInt32(ui_tiempo_espera.Value) * 1000)
                {
                    MessageBox.Show("Superó el tiempo limite ", "Operación cancelada", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                    return;
                }


                //Guardo en una variable el valor para los grados
                int grados = 0;
                if (ui_checkbox_girar.Checked)
                {
                    grados = azar.Next(0, 361);
                }
                else
                {
                    int seleccionar = azar.Next(0, 4);
                    switch (seleccionar)
                    {
                    case 0: grados = 90;
                        break;

                    case 1: grados = 180;
                        break;

                    case 2: grados = 270;
                        break;

                    case 3: grados = 360;
                        break;
                    }
                }

                List <String> nombres_de_formas = new List <string>();
                nombres_de_formas.Add("ui_forma_casa_rectangular");
                //nombres_de_formas.Add("ui_forma_casa_hexagonal");
                nombres_de_formas.Add("ui_forma_casa_deformada");
                nombres_de_formas.Add("ui_forma_casa_deformada_chaflan");

                String vano_ventana_seleccionado = ui_group_box_vanos_ventanas.Controls.OfType <RadioButton>().FirstOrDefault(r => r.Checked).Name;

                //En caso de que una de las casas no encaje y pasaron mas de 10 segundos cambiara su tamaño

                if (cronometro.ElapsedMilliseconds > Convert.ToInt32(ui_tiempo_espera.Value) * 1000 - (Convert.ToInt32(ui_tiempo_espera.Value) * 1000 * 0.1)) //Espera el 90% del tiempo de respuesta
                {
                    anchos[ubicacion_datos] = azar.Next(Convert.ToInt32(ui_min_ancho_casa.Value), Convert.ToInt32(ui_max_ancho_casa.Value) + 1);
                    altos[ubicacion_datos]  = azar.Next(Convert.ToInt32(ui_min_alto_casa.Value), Convert.ToInt32(ui_max_alto_casa.Value) + 1);
                }

                //Subsistema 3.1 seleccion de punto origen segun la distribución

                Point origen = new Point();

                String distribucion_seleccionado = ui_group_box_distribucion.Controls.OfType <RadioButton>().FirstOrDefault(r => r.Checked).Name;

                switch (distribucion_seleccionado)
                {
                case "ui_distribucion_aleatoria":
                    origen = Herramienta.seleccionar_punto_cuadricula(ancho_lienzo - margen_ancho, alto_lienzo - margen_alto, 100, Convert.ToInt32(ui_min_ancho_casa.Value) * 100, Convert.ToInt32(ui_min_alto_casa.Value) * 100);
                    //100 es el multiplo
                    break;

                case "ui_distribucion_columnas":
                    if (y_ori >= (alto_lienzo - Convert.ToInt32(ui_max_alto_casa.Value) * 100) - 400)
                    {
                        x_ori = x_ori + 100;
                        y_ori = Convert.ToInt32(ui_min_alto_casa.Value) * 100;
                    }
                    origen = new Point(x_ori, y_ori);
                    y_ori  = y_ori + 100;
                    break;

                case "ui_distribucion_filas":
                    if (x_ori >= (ancho_lienzo - Convert.ToInt32(ui_max_ancho_casa.Value) * 100) - 400)
                    {
                        x_ori = Convert.ToInt32(ui_min_ancho_casa.Value) * 100;
                        y_ori = y_ori + 100;
                    }
                    origen = new Point(x_ori, y_ori);
                    x_ori  = x_ori + 100;
                    break;
                }

                //Aqui empieza la recollecion de la informacion para las casas

                Info_forma nueva_casa = new Info_forma
                                        (
                    ancho_lienzo,
                    alto_lienzo,
                    anchos[ubicacion_datos],
                    altos[ubicacion_datos],
                    azar.Next(Convert.ToInt32(ui_min_grosor_pared.Value), Convert.ToInt32(ui_max_grosor_pared.Value)),
                    origen, //origen de la forma (casa)
                    new Point(),
                    azar.Next(Convert.ToInt32(ui_pilar_cubico_med_min.Value), Convert.ToInt32(ui_pilar_cubico_med_max.Value)),
                    azar.Next(Convert.ToInt32(ui_pilar_round_med_min.Value), Convert.ToInt32(ui_pilar_round_med_max.Value)),
                    azar.Next(1, Convert.ToInt32(ui_cantidad_pisos.Value) + 1),
                    grados,
                    azar.Next(10, 20), // Este numero se multiplica por el valor de la columna Ej 3 espacio = 90 (30CM)
                    azar.Next(1, 5),
                    ui_checkbox_girar.Checked,
                    Posibilidad,
                    Distancia,
                    ui_pegar_casas.Checked,
                    vano_ventana_seleccionado,
                    nombres_de_formas[azar.Next(0, nombres_de_formas.Count)],
                    azar.Next(Convert.ToInt32(ui_pilar_prox_min.Value), Convert.ToInt32(ui_pilar_prox_max.Value)),
                    azar.Next(Convert.ToInt32(ui_vano_puerta_cant_min.Value), Convert.ToInt32(ui_vano_puerta_cant_max.Value))
                                        );

                nueva_casa.resp_alto_forma  = nueva_casa.alto_forma;
                nueva_casa.resp_ancho_forma = nueva_casa.ancho_forma;


                //Subsistema 3.2 #Filtros

                bool interruptor = false;

                //Verificar si existe interseccion entre casas
                //Esta verificación me deja una gran leccion 29/11/20 :)

                for (int x = 0; x < lista_casas.Count; x++)
                {
                    Parallel.For(0, nueva_casa.area_puntos.Count - 1, (i, state) =>
                    {
                        if (lista_casas[x].area_puntos.Contains(nueva_casa.area_puntos[i]))
                        {
                            //Existe interseccion
                            interruptor = true;
                            state.Break();
                        }
                    });
                }


                //Verifica si existe interseccion entre casas y calles

                if (nueva_casa != null)
                {
                    Parallel.For(0, nueva_casa.area_puntos.Count - 1, (i, state) =>
                    {
                        if (lista_puntos_calles.Contains(nueva_casa.area_puntos[i]))
                        {
                            //Existe interseccion
                            interruptor = true;
                            state.Break();
                        }
                    });
                }

                if (interruptor)
                {
                    ubicacion_datos--;
                    continue;
                }
                else
                {
                    // Si no se encontraron intersecciones agrega la info de forma
                    //nueva_casa.area_post();
                    lista_casas.Add(nueva_casa);

                    if (ui_objetos_elevador.Checked == true)
                    {
                        //Valida que el elevador este dentro del espacio de la forma
                        bool encontrado = false;
                        do
                        {
                            nueva_casa.origen_elevador  = Herramienta.seleccionar_punto_cuadricula(nueva_casa.po.X + nueva_casa.ancho_forma * 100, nueva_casa.po.Y + nueva_casa.alto_forma * 100, 100, nueva_casa.po.X, nueva_casa.po.Y);
                            nueva_casa.espacio_elevador = new Rectangle(nueva_casa.origen_elevador.X, nueva_casa.origen_elevador.Y, 2 * 100, 2 * 100);
                            Rectangle resultado = Rectangle.Intersect(nueva_casa.espacio_elevador, nueva_casa.espacio_forma);
                            if (resultado == nueva_casa.espacio_elevador)
                            {
                                encontrado = true;
                            }
                        } while (encontrado == false);
                    }
                }
            }

            //Subsistema #4 superposiciones
            //Encuentro el nombre del radiobutton de la forma que ha escogido el usuario

            String forma_seleccionada = ui_groupbox_forma_casas.Controls.OfType <RadioButton>().FirstOrDefault(r => r.Checked).Name;

            //Pintar lienzos con los datos almacenados, dependiedo de la superposicion

            if (ui_superposicion_esc_cons.Checked == true)
            {
                for (int i = 0; i < ui_cantidad_pisos.Value; i++)
                {
                    for (int recorrer = 0; recorrer < ui_cantidad_casas.Value; recorrer++)
                    {
                        string nombre_page = "Planta " + i;
                        Formas.forma(forma_seleccionada, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                        //Primero se guardan los nombre de los checkbox activo es una lista

                        List <String> nombres_checkbox = new List <string>();
                        foreach (CheckBox c in ui_groupbox_objetos.Controls.OfType <CheckBox>())
                        {
                            if (c.Checked == true)
                            {
                                nombres_checkbox.Add(c.Name);
                            }
                        }

                        //Después de pintar las casas, se pintan los objetos
                        Objetos.objeto(nombres_checkbox, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                        //Esta variable es modificada una vez que PB se haya dibujado
                        lista_casas[recorrer].ubicacion_pb = false;

                        //Actualización del progress bar #1

                        barra.Value = (int)cropro.Elapsed.TotalSeconds;
                    }
                }
            }
            else if (ui_superposicion_esc_cons_var.Checked == true)
            {
                for (int i = 0; i < ui_cantidad_pisos.Value; i++)
                {
                    for (int recorrer = 0; recorrer < ui_cantidad_casas.Value; recorrer++)
                    {
                        if (lista_casas[recorrer].pisos_reales > 0)
                        {
                            string nombre_page = "Planta " + i;
                            Formas.forma(forma_seleccionada, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                            //Primero se guardan los nombre de los checkbox activo es una lista

                            List <String> nombres_checkbox = new List <string>();
                            foreach (CheckBox c in ui_groupbox_objetos.Controls.OfType <CheckBox>())
                            {
                                if (c.Checked == true)
                                {
                                    nombres_checkbox.Add(c.Name);
                                }
                            }

                            //Después de pintar las casas, se pintan los objetos
                            Objetos.objeto(nombres_checkbox, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                            //Esta variable es modificada una vez que PB se haya dibujado
                            lista_casas[recorrer].ubicacion_pb = false;
                        }
                        lista_casas[recorrer].pisos_reales = lista_casas[recorrer].pisos_reales - 1;

                        //Actualización del progress bar #1

                        barra.Value = (int)cropro.Elapsed.TotalSeconds;
                    }
                }
            }
            else if (ui_superposicion_piramidal.Checked == true)
            {
                for (int i = 0; i < ui_cantidad_pisos.Value; i++)
                {
                    for (int recorrer = 0; recorrer < ui_cantidad_casas.Value; recorrer++)
                    {
                        if (i > 0)
                        {
                            int valor_reduccion = 0;
                            if (ui_superposicion_rad_valor_fijo.Checked == true)
                            {
                                valor_reduccion = Convert.ToInt32(ui_superposicion_valor_fijo.Value);
                            }
                            else if (ui_superposicion_rad_valor_por_rango.Checked == true)
                            {
                                int limite = Math.Min(lista_casas[recorrer].alto_forma, lista_casas[recorrer].ancho_forma);
                                //Esto es para manejar la excepcion probar un break
                                if (limite < 0)
                                {
                                    limite = 0;
                                }

                                int modo = 0;
                                valor_reduccion = azar.Next(modo, limite + 1);
                            }
                            lista_casas[recorrer].nuevo_origen = new Point(lista_casas[recorrer].po.X + ((valor_reduccion * 100) / 2), lista_casas[recorrer].po.Y + ((valor_reduccion * 100) / 2));
                            lista_casas[recorrer].po           = lista_casas[recorrer].nuevo_origen;
                            lista_casas[recorrer].ancho_forma  = lista_casas[recorrer].ancho_forma - valor_reduccion;
                            lista_casas[recorrer].alto_forma   = lista_casas[recorrer].alto_forma - valor_reduccion;
                        }

                        if (lista_casas[recorrer].ancho_forma > 2 && lista_casas[recorrer].alto_forma > 2)
                        {
                            string nombre_page = "Planta " + i;
                            Formas.forma(forma_seleccionada, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                            //Después de pintar las casas, se pintan los objetos

                            //Primero se guardan los nombre de los checkbox activo es una lista

                            List <String> nombres_checkbox = new List <string>();
                            foreach (CheckBox c in ui_groupbox_objetos.Controls.OfType <CheckBox>())
                            {
                                if (c.Checked == true)
                                {
                                    nombres_checkbox.Add(c.Name);
                                }
                            }

                            Objetos.objeto(nombres_checkbox, lista_casas[recorrer], (PictureBox)TabControl.TabPages[i].Controls.Find(nombre_page, true)[0]);

                            //Esta variable es modificada una vez que PB se haya dibujado
                            lista_casas[recorrer].ubicacion_pb = false;
                        }


                        //Actualización del progress bar #1

                        barra.Value = (int)cropro.Elapsed.TotalSeconds;
                    }
                }
            }
            MessageBox.Show("Completado exitosamente", "Información", MessageBoxButtons.OK, MessageBoxIcon.Information);
            barra.Value = 0;
        }