UNIVERSIDAD PONTIFICIA COMILLAS ESCUELA TÉCNICA SUPERIOR DE INGENIERÍA (ICAI) INGENIERO INDUSTRIAL PROYECTO FIN DE CARRERA Programa gráfico para el posicionamiento de seguidores en huertas solares fotovoltaicas conectadas a red AUTOR: Paula Calles Ayastuy MADRID, Septiembre de 2007 Resumen Actualmente existen muchos factores que están provocando una grave crisis tanto energética como medioambiental. Por un lado, el cercano agotamiento de los combustibles fósiles evidencia la necesidad de disponer de otros sistemas eficientes de generación de energía. Además, el crecimiento desproporcionado de la demanda que no se corresponde con el de la generación plantea la necesidad de diversificar las fuentes de energía y la posibilidad de su uso a pequeña escala que no precisen de sistemas de distribución de electricidad (especialmente recomendable en el caso de las energías renovables). Finalmente el cambio climático está impulsando una elevada restricción medioambiental orientada a aumentar las inversiones en energías renovables. Dentro de las energías renovables encontramos la Solar fotovoltaica para la que España, por su privilegiada situación y climatología, está especialmente indicada. El presente proyecto trata de facilitar la instalación de sistemas de generación de energías renovables, concretamente de huertas solares fotovoltaicas conectadas a red las cuales se realizan mediante seguidores solares. Este tipo de instalaciones está experimentando un gran desarrollo en España debido a las propicias condiciones en que está situado dado que las compañías distribuidoras están obligadas a comprar la energía generada por este tipo de instalaciones. El problema que presenta este tipo de instalaciones es el de calcular las distancias entre seguidores. Hasta el momento, el cálculo de la proyección de sombras entre seguidores debe realizarse manualmente lo que implica una gran pérdida de tiempo. Algunos fabricantes de seguidores solares adjuntan recomendaciones sobre las distancias a guardar según el tipo de seguidor; sin embargo, estas distancias son muy genéricas y en muchos casos, muy conservadoras. En el caso de que el fabricante no realice ninguna recomendación, el valor de la distancia que suele utilizarse es el que se obtiene de calcular la sombra que proyecta un seguidor a las 12 del mediodía solar del día correspondiente al solsticio de invierno (21 de Diciembre); día en el que la sombra es más alargada. Sin embargo, este cálculo es muy poco preciso puesto que no permite saber a lo largo del año la cantidad de sombra que va a recibir cada seguidor, dato que permitiría realizar un diseño más preciso según las necesidades. El problema de las sombras es especialmente importante en el caso de la energía solar fotovoltaica debido a su funcionamiento. La capacidad de generar energía eléctrica de una célula fotovoltaica está supeditada a la presencia de radiación solar incidente sobre ella, por lo que en el momento en el que ésta desaparezca, la célula dejará de generar. Lo que pretende el presente proyecto es facilitar una herramienta que permita realizar dichos cálculos de forma clara y rápida con la finalidad de que el responsable de diseñar la instalación pueda escoger, en base a los criterios propios de cada proyecto, la disposición que más le convenga. Primero se hizo un estudio del problema con el fin de decidir las mejoras que se podían conseguir. Por un lado, la dificultad que suponía la utilización de las ecuaciones tridimensionales del movimiento del Sol se simplifica enormemente mediante la programación. Además, manualmente resulta inviable hacer el cálculo de la sombra proyectada por un seguidor a lo largo de todo el año y más aún si se tiene en cuenta que para ver la sombra que incide sobre un seguidor habrá que calcular la que proyectan todos los que le rodean. En programación, mediante bucles resulta bastante sencillo realizar esta operación. Al irse desarrollando el diseño del proyecto ha habido que hacer frente a diferentes problemas derivados de la programación. Lo que implica un mayor número de problemas es el hecho de que el diseño debe realizarse para un caso lo más genérico posible. El resultado final es un programa que, introduciéndole los datos referentes al seguidor: Base de la parrilla de módulos, Altura de la parrilla de módulos, Altura de la columna del seguidor y ángulo máximo de inclinación del seguidor, una disposición de la huerta mediante un plano de AutoCAD y la ubicación de la instalación, muestra la sombra que va a incidir sobre cada seguidor cada mes del año. La herramienta utilizada para presentar los resultados es Microsoft Excel puesto que permite al usuario, una vez finalizado el programa utilizar y manipular los datos obtenidos. Dada la facilidad de uso del programa y la rapidez con la que permite realizar estos cálculos, el usuario puede probar fácilmente varias disposiciones distintas y varios seguidores diferentes para después, con ayuda de los valores obtenidos, decidir cuál es la que más le interesa. Como conclusión cabe destacar que este programa por sí mismo resulta una herramienta muy útil a la hora de diseñar la disposición de los seguidores fotovoltaicos en huertas solares conectadas a red; sin embargo, también puede utilizarse como base para desarrollar programas más complejos en este mismo ámbito. Por ejemplo para realizar un programa que dibuje las sombras en cada uno de los seguidores o uno que calcule dichas sombras pudiendo colocar en cada posición seguidores diferentes bastaría con ampliar el presente proyecto. Summary Many of circumstances are currently leading up to a serious crisis in both, the energy and environmental fields. On the one hand, the imminent running out of fossil fuels shows that other efficient energy generating systems are required. Besides the fact that the huge increase in the demand of energy which is not consistent with the generation, gives raise to the need of diversifying the energy sources and the need of using such sources on a small scale which do not require an electricity supply network (strongly recommended in case of renewable energy). Finally, many environmental restrictions in support of increasing the investment in renewable energy are being caused by the climatic change. Within the renewable energies the photovoltaic energy is included. Due to the geographical circumstances and the climatic conditions of Spain, this energy is specially suitable in this country. The purpose of this project is to make easier the instalment of renewable energy’s generating systems. In particular, the installation of photovoltaic farms connected to the network which are carried out by means of sun trackers. This kind of installations are growing and developing in Spain due to the fact that the energy supply companies are bound to purchase the energy produced by such installations. The calculation of the distance that must be kept between the sun trackers would be the most inconvenience identified in this kind of installations. So far, the estimation of the shadow projected between sun trackers must be carried out manually, this leading up to an important waste of time. A number of sun trackers’ manufacturers do attach their advises on the distance that should be kept depending on the type of sun trakers.Albeit this advise is commonly a generic distance and, in many occasions, very conservative. In cases where no advise is given by the manufacturer, the distance is commonly obtained from calculating the shadow which is projected by a sun tracker at 12 p.m. in the winter solstice (i.e. 21st December). This is the day of the year with the most extended shadow. However, this calculation is not very precise since there is no way to be aware of the quantity of shadow that each of the sun trackers would receive during the year. This data would allow to carry out a more precise design depending on the particular needs. Because of the operation of the solar photovoltaic energy, the problem of the shadow is specially relevant. The electricity generating capacity of a photovoltaic cell is subject to the solar radiation affecting the cell. For that reason, the cell will stop generating as soon as the radiation disappears. The aim of this project is to provide a tool which enables calculating on a clear and quick manner. This way, the person in charge of designing the installation will be able to choose the most convenience layout/arrangement in view of the criteria to be followed in each project. At a previous step, the problem was analyzed in order to evaluate the improvements that could be achieved. By way of programming, the difficulty of using the equations of the Sun’s movement was simplified. Additionally, it is unfeasible to calculate the shadow which is projected by a sun tracker during the whole year. Even more considering that for the shadow affecting a particular sun tracker to be obtained, it is required to calculate the one projected by the other sun trackers nearby. In programming, this operation is quite easy by means of loops. Whilst developing the design of this project, a number of problems arising out of programming have been faced. The most relevant inconvenience being that the design must be carried out for a single case, as more generic as possible. The final result is a program which, by including the data in connection with the sun tracker: the base and the height of the sun trackers, iii) height of the sun tracker’s column and the maximum inclination angle of the sun trackers, iv) the layout of the farm by an AutoCAD design and v) the arrangement of the installation, shows the shadow that will be affecting each of the sun trakers during each month in a year. Given that Microsoft Excel enables the user changing and manipulating the data obtained once the program has been finalized, this tool has been chosen to show the results. Provided the easiness of the program and the quick the calculus are made, the user can easily try a number of different layouts and different sun trackers. In view of the values obtained, the user will be able to decide which of them is the most advisable one. By way of conclusion, it should be highlighted that this program appears to be a very useful tool when designing the layout of photovoltaic sun trackers in solar farms connected to the network. Additionally, appears to be also useful for developing more complex programs in this same field. This program would be the basis of the most complex one. For instance, in order to carry out a program which either draws each of the sun trackers’ shadow or calculates such shadows allowing the possibility of establishing different sun trakers in every position, it will be enough by extending the current project. INDICE 1 Introducción y planteamiento del proyecto…… 1 1.1 Introducción…………………………………………………… 2 1.1.1 La energía solar………………………………………………….. 4 1.1.2 Energía solar fotovoltaica…………………………………….. 4 1.2 Planteamiento del proyecto…………………………………… 8 2 Descripción de las tecnologías……………………… 11 3 Descripción d el modelo desarrollado…………… 15 3.1 Objetivos y especificación……………………………… 16 3.1.1 Objetivos……………………………………………………………. 16 3.1.2 Especificación……………………………………………………… 16 3.1.2.1 Especificaciones del seguidor………………………… 16 3.1.2.2 Especificaciones de la disposición…………………… 16 3.1.2.3 Especificaciones de la ubicación del terreno…… 17 3.2 Datos………………………………………………………………….. 17 3.2.1 Introducción de datos…………………………………………. 17 3.2.1.1 Dimensiones del seguidor……………………………… 17 3.2.1.2 Distribución de los seguidores………………………. 17 3.2.1.3 Ubicación de la instalación………………………….… 18 3.3 Algoritmos…………………………………………………………… 18 3.3.1 Cálculos previos al código…………………………………….. 19 3.3.1.1 Ejes fijos y ejes solidarios al seguidor……………… 22 3.3.1.2 Coordenadas de un seguidor genérico……………… 23 3.3.1.3 Proyección de la sombra………………………………… 26 3.3.1.4 Calculo de sombra sobre un seguidor genérico…. 27 3.3.1.4.1 Seguidor nº1………………………………. 30 3.3.1.4.2 Seguidor nº2………………………………. 30 3.3.1.4.3 Seguidor nº3………………………………. 31 3.3.1.4.4 Seguidor nº4………………………………. 31 3.3.1.4.5 Seguidor nº5………………………………. 32 3.3.1.4.6 Seguidor nº6………………………………. 32 3.3.1.4.7 Seguidor nº7………………………………. 33 3.3.1.4.8 Seguidor nº8………………………………. 33 3.3.2 Desarrollo del código……………………………………………. 34 3.3.2.1 Obtención de datos desde un plano de Autocad…. 34 3.3.2.2 Procesamiento de los datos…………………………….. 42 3.3.2.2.1 El movimiento del Sol……………………. 43 3.3.2.2.1.1 La Latitud…………………………………………………………. 43 3.3.2.2.1.2 La posición del sol……………………………………………… 45 3.3.2.2.2 Posición del seguidor…………………….. 52 3.3.2.2.2.1 Coordenadas locales del seguidor………………………… 53 3.3.2.2.2.2 Coordenadas globales del seguidor………………………. 57 3.3.2.2.3 Cálculo de la sombra……………………… 59 3.3.2.2.3.1 Longitud de la sombra………………………………………… 59 3.3.2.2.3.2 Coordenadas locales de la sombra………………………. 62 3.3.2.2.3.3 Coordenadas globales de la sombra……………………… 63 3.3.2.2.4 Cálculo de las pérdidas por sombra…. 64 3.3.2.2.4.1 3.3.2.2.4.2 3.3.2.2.4.3 3.3.2.2.4.4 3.3.2.2.4.5 3.3.2.2.4.6 3.3.2.2.4.7 3.3.2.2.4.8 Seguidor Seguidor Seguidor Seguidor Seguidor Seguidor Seguidor Seguidor nº1……………………………………………………… nº2……………………………………………………… nº3……………………………………………………… nº4……………………………………………………… nº5……………………………………………………… nº6……………………………………………………… nº7……………………………………………………… nº8……………………………………………………… 66 68 69 70 71 72 73 74 3.3.2.2.5 Final del programa………………………. 75 3.3.2.3 Presentación de los resultados en tabla de Excel. 77 3.4 Implantación numérica………………………………………. 78 4 Análisis de los resultados……………………………………… 83 4.1 4.2 4.3 4.4 5 Caso Caso Caso Caso 1……………………………………………………………………. 85 1-2…………………………………………………………………. 85 2-3…………………………………………………………………. 87 3-4…………………………………………………………………. 87 Conclusiones…………………………………………………………… 89 5.1 Conclusiones sobre los resultados…………………………….. 90 5.2 Recomendaciones para futuros estudios……………………. 90 6 Bibliografía……………………………………………………………… 91 7 Apéndice………………………………………………………………… 93 7.1 Estructuras de decisión……………………………………… 95 7.1.1 Sentencia IF ... THEN ... ELSE ... ……………………………… 95 7.1.2 Sentencia SELECT CASE…………………………………........... 96 7.2 Estructuras de bucle…………………………….................... 97 7.2.1 Sentencia FOR ... NEXT…………………………………............ 97 7.2.2 Sentencia DO…LOOP……………………………………............. 98 8. Código…………………………………………………………............... 99 1 Caracterización de la demanda 1 Introducción y planteamiento del proyecto 1 1.1 Introducción La energía es fundamental para el desarrollo económico de un país y para el bienestar de su población. Forma parte del instrumental económico, pues se la requiere para activar todo tipo de maquinaria o herramienta y, aunque no se incorpora materialmente a los bienes o servicios producidos, tiene incidencia en los costos de producción. Además, es un bien de consumo final que se utiliza para la satisfacción (para el confort) humano. Esto la convierte en un bien estratégico y su disponibilidad resulta primordial. La seguridad en el abastecimiento energético requiere de un equilibrio entre las diversas fuentes energéticas, a fin de evitar o reducir nuestra exposición a eventuales problemas en el suministro. En este sentido, a fin de contribuir a tener una mayor seguridad, es necesaria una correcta diversificación en el suministro y distribución de energía, tanto para los diferentes tipos de energía como de las distintas fuentes. La energía es un bien básico y estratégico que se encuentra en la agenda actual de todos los países o regiones comerciales. Hechos como el desajuste entre oferta y demanda de combustibles fósiles y el consiguiente efecto sobre los precios, o las restricciones en el suministro de gas, han suscitado un debate sobre el futuro energético mundial y la elaboración de estrategias que permitan no sólo garantizar el suministro energético a largo plazo sino también conforme a unos criterios de responsabilidad medioambiental. España no es ajena a este contexto de preocupación. Muy al contrario, tenemos mayores motivos de inquietud: un grado de dependencia energética superior al 80%; inseguridad en el actual armazón regulatorio del sector; indefinición sobre el uso en el futuro de determinadas fuentes de energía; elevada restricción medioambiental y pérdida de peso en los escenarios internacionales. Sin embargo, también contamos con otros elementos a favor como un mix tecnológico bien diversificado; una posición ventajosa en el desarrollo de energías renovables. La elevada dependencia de las importaciones para satisfacer la demanda española de energía pone en evidencia otra de las características de nuestro patrón energético: su vulnerabilidad. Más del 65% del consumo energético en el Estado español descansa sobre los combustibles fósiles, de los que apenas producimos un 2%. El resto lo importamos de países que (en total importamos un 80% de nuestros recursos energéticos), en un momento dado, podrían cortar el suministro; entre otros motivos, porque tengan que hacer frente a su propia demanda interna. Es por esto que para España, y mas concretamente para su estructura productiva, 2 resulta esencial superar las debilidades que presenta el actual modelo energético, con el fin de elevar la eficiencia y reducir la dependencia del petróleo y la consiguiente vulnerabilidad ante las fluctuaciones de los mercados internacionales de este recurso. Por otro lado, las emisiones de gases de efecto invernadero (derivadas de la combustión de estos recursos fósiles) seguirán sobrepasando con creces los compromisos fijados De todo lo expuesto se deduce que el balance energético español es lamentable, por lo que resulta absolutamente necesario potenciar las energías renovables. Se denominan energías renovables a aquellas que se obtienen de fuentes naturales virtualmente inagotables, unas por la inmensa cantidad de energía que contienen, y otras porque son capaces de regenerarse por medios naturales. Las fuentes renovables de energía pueden dividirse en dos categorías: no contaminantes o limpias y contaminantes. Entre las primeras encontramos la energía solar, energía eólica, energía hidráulica, energía mareomotriz, energía geotérmica. En el caso de las contaminantes, que son las realmente renovables, se obtienen a partir de la materia orgánica o biomasa, y se pueden utilizar directamente como combustible o bien convertida en bioetanol o biogás mediante procesos de fermentación orgánica o en biodiésel, mediante reacciones de transesterificación. Hace tiempo que las energías renovables se han considerado como una alternativa a las energías tradicionales, tanto por su disponibilidad presente y futura garantizada (a diferencia de los combustibles fósiles que precisan miles de años para su formación) como por su menor impacto ambiental en el caso de las energías limpias Según la Comisión Nacional de Energía española, la venta anual de energía del Régimen Especial se ha multiplicado por más de 10 en España, a la vez que sus precios se han rebajado un 11 %. Se considera que el Sol abastecerá estas fuentes de energía (radiación solar, viento, lluvia, etc.) durante los próximos cuatro mil millones de años. La primera ventaja de la mayor cantidad de fuentes de energía renovables es que no producen gases de efecto invernadero ni otras emisiones, contrariamente a lo que ocurre con los combustibles, sean fósiles o renovables. Algunas fuentes renovables no emiten dióxido de carbono adicional, salvo los necesarios para su construcción y funcionamiento, y no presentan ningún riesgo suplementario, tales como el riesgo nuclear. 3 Además, el uso a pequeña escala de energías renovables, que a menudo puede producirse "in situ", disminuye la necesidad de disponer de sistemas de distribución de electricidad. Los sistemas corrientes, raramente rentables económicamente, revelaron que un hogar medio que disponga de un sistema solar con almacenamiento de energía, y paneles de un tamaño suficiente, sólo tiene que recurrir a fuentes de electricidad exteriores algunas horas por semana. Por lo tanto, las ventajas más significativas derivadas del uso de las energías renovables serían: no emiten CO2 a la atmósfera y evitan así el proceso de calentamiento terrestre como consecuencia del efecto invernadero, no contribuyen a la formación de lluvia ácida, no dan lugar a la formación de NOx , no necesitan sofisticadas medidas de seguridad dado que no producen residuos tóxicos de difícil o imposible tratamiento o eliminación. Los impactos derivados de estas energías son de menor dimensión y más localizados, por lo tanto más fácilmente corregibles o controlables. Además sus efectos no son permanentes ya que no se prolongan después de la utilización de la fuente energética. 1.1.1 La energía solar El Sol, fuente de vida y origen de las demás formas de energía que el hombre ha utilizado desde los albores de la Historia, puede satisfacer todas nuestras necesidades, si aprendemos cómo aprovechar de forma racional la luz que continuamente derrama sobre el planeta. Ha brillado en el cielo desde hace unos cinco mil millones de años, y se calcula que todavía no ha llegado ni a la mitad de su existencia. Durante el presente año, el Sol arrojará sobre la Tierra cuatro mil veces más energía que la que vamos a consumir. España, por su privilegiada situación y climatología, se ve particularmente favorecida respecto al resto de los países de Europa, ya que sobre cada metro cuadrado de su suelo inciden al año unos 1.500 kilovatios-hora de energía, cifra similar a la de muchas regiones de América Central y del Sur. Esta energía puede aprovecharse directamente, o bien ser convertida en otras formas útiles como, por ejemplo, en electricidad. No sería racional no intentar aprovechar, por todos los medios técnicamente posibles, esta fuente energética gratuita, limpia e inagotable, que puede liberarnos definitivamente de la dependencia del petróleo o de otras alternativas poco seguras, contaminantes o, simplemente, agotables. Es preciso, no obstante, señalar que existen algunos problemas que debemos afrontar y superar. 4 Aparte de las dificultades que una política energética solar avanzada conllevaría por sí misma, hay que tener en cuenta que esta energía está sometida a continuas fluctuaciones y a variaciones más o menos bruscas. Así, por ejemplo, la radiación solar es menor en invierno, precisamente cuando más la solemos necesitar. Es de vital importancia proseguir con el desarrollo de la incipiente tecnología de captación, acumulación y distribución de la energía solar, para conseguir las condiciones que la hagan definitivamente competitiva, a escala planetaria. 1.1.2 Energía solar fotovoltaica Las «células solares», dispuestas en paneles solares, ya producían electricidad en los primeros satélites espaciales. Actualmente se perfilan como la solución definitiva al problema de la electrificación rural, con clara ventaja sobre otras alternativas, pues, al carecer los paneles de partes móviles, resultan totalmente inalterables al paso del tiempo, no contaminan ni producen ningún ruido en absoluto, no consumen combustible y no necesitan mantenimiento. Además, y aunque con menos rendimiento, funcionan también en días nublados, puesto que captan la luz que se filtra a través de las nubes. La electricidad que así se obtiene puede usarse de manera directa (por ejemplo para sacar agua de un pozo o para regar, mediante un motor eléctrico), o bien ser almacenada en acumuladores para usarse en las horas nocturnas. También es posible inyectar la electricidad generada en la red general, obteniendo un importante beneficio. Si se consigue que el precio de las células solares siga disminuyendo, iniciándose su fabricación a gran escala, es muy probable que, para la segunda década del siglo, una buena parte de la electricidad consumida en los países ricos en sol tenga su origen en la conversión fotovoltaica. La energía solar puede ser perfectamente complementada con otras energías convencionales, para evitar la necesidad de grandes y costosos sistemas de acumulación. Así, una casa bien aislada puede disponer de agua caliente y calefacción solares, con el apoyo de un sistema convencional a gas o eléctrico que únicamente funcionaría en los periodos sin sol. El coste de la «factura de la luz» sería sólo una fracción del que alcanzaría sin la existencia de la instalación solar. 5 Desde que la conservación de las fuentes de energía no renovables empezó a tratarse como una necesidad, los desarrollos que se han producido en el aprovechamiento de las energías renovables han sido espectaculares. En concreto, el actual mercado fotovoltaico crece de forma contundente y lo más importante respaldado • por un interés gubernamental. Previsiones de potencia a instalar Debemos remitirnos al Plan de Fomento de las Energías Renovables. El Consejo de Ministros (30/12/1999) aprobó el Plan de Fomento de las Energías Renovables para el período 2000-2010. El Plan es una planificación de carácter indicativo que recoge los principales elementos y orientaciones para la articulación de una estrategia que logre que el crecimiento de cada una de las áreas de energías renovables pueda cubrir, en su conjunto, al menos el 12 por 100 del consumo de energía primaria en España en el año 2010, que es el objetivo que recoge la Ley 54/1997 del Sector Eléctrico. Así, las energías renovables en el año 2010 deberán aportar al abastecimiento nacional 16,6 millones de tep, frente a los 7,1 millones de tep actuales. Este objetivo implica duplicar la participación de estas energías en el consumo de energía primaria. La planificación propuesta tiene un marcado carácter indicativo al definirse en un contexto, en el marco de la UE, de liberación creciente hacia un Mercado Único de la energía. Sin embargo, por su carácter estratégico y beneficios intrínsecos, presentes en diversos ámbitos, a las energías renovables se les otorga un tratamiento específico diferenciado. Con la ejecución de este Plan, además de cubrirse el 12,3 por 100 de la demanda total de energía en España en el año 2010 con energías renovables, se consiguen los principales objetivos trazados para la política energética nacional: la diversificación de las fuentes primarias para garantizar la seguridad en el suministro energético, la eficiencia en su utilización y el respeto al medio ambiente. Por otro lado, el Plan de Fomento se revela como un instrumento indispensable para alcanzar los compromisos adquiridos por España en el campo medioambiental, en concreto en materia de limitación de las emisiones de gases de efecto invernadero. 6 Como principales efectos derivados de la ejecución del Plan cabe citar: •Fortalecimiento y conformación de un moderno tejido industrial para el sector a través del desarrollo y la puesta en el mercado de tecnologías propias que producirán unos efectos de importancia creciente sobre la exportación. Se podría establecer en más de 1.000 el número de empresas que hasta el año 2006 pueden surgir para el aprovechamiento directo de las energías renovables, lo que contribuirá de forma efectiva a la creación de empleo. •El ahorro de emisiones de CO2 derivado de la ejecución del Plan se ha estimado entre 19,5 y 41,5 millones de toneladas en el año 2010, según las fuentes de energías renovables sustituyan, respectivamente, al gas natural o al carbón para la generación de energía eléctrica. Las energías y áreas técnicas que considera el Plan son: biomasa, de la cual se aprovecha su contenido energético en una primera transformación (residuos agrícolas, forestales, cultivos energéticos, etcétera) o en una segunda etapa (residuos animales transformados a biogás, biocarburante, etcétera); eólica; aprovechamiento de la energía cinética del viento; hidráulica, aprovechamiento de la energía potencial del agua; solar: energía solar térmica en sus diversas transformaciones (pasiva, directa y termoeléctrica) y fotovoltaica; y valorización energética de residuos urbanos (biogás, sólidos, etcétera). Los datos más relevantes sobre solar fotovoltaica que define el Plan los encontramos resumidos en la siguiente tabla. El Plan de Fomento de las Energías Renovables tiene como previsión el instalar durante el período 2000-2010, 135 MWp nuevos en sistemas fotovoltaicos. De esta cantidad, aproximadamente 20 MWp podrían corresponder a aplicaciones aisladas de la red y 115 MWp a aplicaciones conectadas. Detalle sobre el gráfico anterior en la siguiente tabla: • Ventajas e inconvenientes Las ventajas de la energía solar fotovoltaica son numerosas. En primer lugar, son sistemas silenciosos, limpios y respetuosos con el medio ambiente, y suponen un gran ahorro en el traslado de energía, puesto que se encuentran cerca del punto de consumo. Cuando se trata de centrales fotovoltaicas, se requiere poco tiempo para su construcción, cerca de las localidades a las que tiene que suministrar energía. En el caso de los paneles fotovoltaicos instalados en las 7 viviendas, éstos requieren un mínimo mantenimiento ofreciendo un gran periodo de vida útil, con lo que se amortiza en un breve periodo de tiempo. En definitiva, su uso ofrece un suministro de energía continuo y fiable sin tener que depender de las fuentes de energía convencional. En cuanto a los inconvenientes, las instalaciones fotovoltaicas tienen unas limitaciones que deben llevar a sus usuarios a la moderación en el consumo y al empleo de aparatos de consumo con elevados rendimientos. Asimismo, el precio y el gran tamaño de los paneles solares frenan su expansión, puesto que la tecnología disponible actualmente requiere de una gran superficie de captación. 1.2 Planteamiento del proyecto El presente proyecto trata de facilitar la instalación de sistemas de generación de energías renovables, concretamente de huertas solares fotovoltaicas conectadas a red las cuales se realizan mediante seguidores solares. Como ya se ha comentado en la introducción, este tipo de instalaciones está experimentando un gran desarrollo en España. En este tipo de instalación resulta especialmente importante la disposición con la que van a instalarse los seguidores; sin embargo, dada la situación actual, resulta especialmente difícil y tedioso obtener unos valores óptimos para la disposición. Por lo tanto, la motivación principal a la hora de realizar este proyecto surge de la inexistencia de un software comercial genérico para todo generador por lo que resultaría interesante la implantación de un sistema de cálculo de sombras con el fin de hallar la mejor disposición para los seguidores comerciales con la que conseguir el máximo aprovechamiento solar. Debido a la inexistencia de un software con las características comentadas, hasta el momento el cálculo de la proyección de sombras entre seguidores debía realizarse manualmente lo que implica una gran pérdida de tiempo. Para realizar un exhaustivo cálculo de la sombra que incide sobre un seguidor dispuesto en una huerta solar, hay que tener en cuenta tanto la posición del sol como la del seguidor. El problema es que ambas varían a cada momento por lo que el número de cálculos puede ser infinito. Dado que es imposible realizarlos para cada instalación, se utilizan algunas soluciones con sus correspondientes limitaciones. 8 Algunos fabricantes de seguidores solares adjuntan recomendaciones sobre las distancias a guardar según el tipo de seguidor; sin embargo, estas distancias son muy genéricas y en muchos casos, muy conservadoras. En otros casos se proponen unas distancias según el incremento de rendimiento deseado, pero nuevamente resultan demasiado poco particulares. Además, no permiten saber realmente los valores de incremento de rendimiento o de porcentaje de sombra. Cuando el fabricante no realiza ninguna recomendación, los cálculos debe realizarlos el propio diseñador de la instalación. En estos casos se recomienda efectuar los cálculos para el día del solsticio de invierno, que es cuando la trayectoria del sol es más baja y, por lo tanto, las sombras alcanzan su máxima longitud sobre el suelo. Concretamente, estos cálculos suelen realizarse para el mediodía solar de dicho día. Sin embargo, utilizando las distancias así calculadas, durante un amplio intervalo de días, especialmente en los meses de diciembre y enero, se producirá sombreado en los seguidores y por lo tanto es posible que durante esos meses apenas pueda ser inyectada energía útil a la red, a pesar de que los paneles puedan recibir en esos meses una apreciable cantidad de radiación. Este problema es exclusivo de los paneles fotovoltaicos puesto que en el caso de los colectores térmicos, el anterior sombreado no tendría más consecuencia que una pequeña disminución en su rendimiento durante el invierno. La razón por la que la incidencia de sombras resulta tan decisiva para el rendimiento de una instalación fotovoltaica reside en el funcionamiento de las células fotovoltaicas. El principio de funcionamiento de las mismas es el siguiente: 9 o La unión de dos elementos semiconductores, uno de tipo N y otro de tipo P, provoca una diferencia de potencial en las proximidades de esa unión. o Los fotones transfieren la energía de la radiación solar incidente a los electrones de los semiconductores, liberándolos de la red cristalina a la que estaban unidos (generación electrón-hueco) o La diferencia de potencial existente en la unión provoca un flujo ordenado de portadores (electrones y huecos) fotogenerados, originando una diferencia neta de potencial en la célula. o Mediante los contactos existentes en la célula, puede disponerse un circuito exterior, por el que circulará una corriente eléctrica, la cual podrá entregar potencia eléctrica útil. La diferencia de potencial existente entre los extremos de la célula solar fotovoltaica se debe a la separación espacial de los portadores fotogenerados. Estos potadores sólo mantienen su condición de “libres” durante un tiempo limitado, al cabo del cual se recombinan y pierden su capacidad para formar parte de una corriente eléctrica por lo que su funcionamiento requiere de la presencia de la radiación solar incidente. Por todo lo expuesto, lo que pretende el presente proyecto es facilitar una herramienta que permita realizar los cálculos de sombras de forma clara y rápida con la finalidad de facilitar la optimización de las inatalaciones de huertas solares fotovoltaicas conectadas a red. 10 2 cterización de la demanda 2 Descripción de las tecnologías 3 Caracterización de la demanda 11 Para el desarrollo del proyecto se han utilizado tres programas relacionándolos entre sí: o AutoCAD o Microsoft Excel o Visual Basic 6 Básicamente, la herramienta que sirve de unión es el Visual Basic, además es este programa el que lleva el peso del proyecto. Visual Basic es una herramienta de programación que permite crear aplicaciones para Microsoft Windows. De cara a este proyecto, la ventaja que presenta Visual Basic frente a otras herramientas de programación es que esta permite programar aplicaciones tanto para Excel como para AutoCAD. Además la aplicación terminada es un auténtico .exe que utiliza una máquina virtual que se puede distribuir sin necesidad de tener el programa de Visual Basic AutoCad es una herramienta de dibujo, que en este caso va a utilizarse como entrada de datos, mediante un plano. Realmente utiliza el archivo .dxf correspondiente al plano. AutoCAD DXF (Drawing Exchange Format) es un formato de archivo desarrollado por AutoDesk para facilitar el intercambio de dibujos de AutoCAD con otros programas de CAD. Es un archivo que contiene el código del dibujo de AutoCAD de tal forma que puede leerse como un archivo de texto. Esta última cualidad es la que se ha aprovechado en el proyecto para facilitar la obtención de datos del plano. Microsoft Excel es un programa de hoja de cálculo. En el presente proyecto, este programa se utiliza para presentar mediante una tabla el resultado obtenido mediante el programa que se ha desarrollado. Una de las razones por la que se ha elegido este programa es que, una vez obtenidos los resultados, pueden ser utilizados para realizar otras operaciones. Microsoft Excel también se utiliza para realizar un intercambio dinámico de datos con Visual Basic; esto permite obtener de una tabla memorizada en Excel un dato necesario para el desarrollo del programa. 12 La forma en la que se relacionan estas tres herramientas y, por lo tanto, la forma en la que se desarrolla el programa es el siguiente: o El usuario introduce los datos que el .exe le pide, entre ellos la ubicación del plano de AutoCAD (el archivo DXF del plano) o Mediante Visual Basic se transforman los datos, los que lo necesiten, a un formato útil para su manejo. Esto se realiza de dos formas: Se abre el archivo DXF del plano y mediante un archivo de texto se extraen los datos de situación de los seguidores. Estos datos son colocados en matrices. Se abre en Excel la tabla asociada a las latitudes de las Comunidades Autónomas y se realiza un intercambio de datos entre Visual Basic y Excel de forma que se obtiene el valor de la latitud correspondiente a la Comunidad escogida. Se cierra la tabla. Se procesan todos los datos hasta obtener los resultados deseados, los porcentajes de sombra de cada seguidor en cada mes. Se crea una tabla en Excel donde con los resultados obtenidos. En la siguiente figura se muestra el flujo de información entre los programas: 13 14 3 Descripción del modelo desarrollado 15 3.1 Objetivos y especificación. 3.1.1 Objetivos o Establecimiento de criterios para el cálculo de sombras o Cálculo de sombras para la generación de seguidores o Implantación en ecuaciones tridimensionales de la geometría solar o Ofrecer una herramienta que permita optimizar la energía solar en las huertas solares fotovoltaicas. 3.1.2 Especificación Las especificaciones para el presente proyecto se en tres apartados. Las especificaciones de los seguidores para los que se va a diseñar el programa, de la disposición de los mismos y por último, la ubicación del terreno. 3.1.2.1 Especificaciones del seguidor. A pesar de existir muchos tipos de seguidores, los que se han utilizado para diseñar este proyecto han sido los seguidores de dos ejes puesto que permiten realizar un seguimiento casi completo del movimiento del sol. Esto implica que la posición del seguidor en cada momento viene determinada por la posición del Sol o, lo que es lo mismo, las variables que la determinan. Sin embargo, hay que tener en cuenta que éstos seguidores tienen algunas limitaciones. La más importante a la hora del diseño de este proyecto es que tienen un ángulo máximo de inclinación por lo que el seguidor no siempre se mantendrá perpendicular a los rayos del sol en cuanto a lo que altura solar se refiere. Cuando la altura solar sea inferior a dicho ángulo máximo, el seguidor se mantendrá con dicha inclinación aunque la altura solar disminuya. 3.1.2.2 Especificaciones de la disposición. Como disposición genérica se ha utilizado una bastante habitual y que coincide con la recomendación de los fabricantes de diseñadores. Se trata de un marco de implantación rectangular respecto a los ejes Norte-Sur y Este-Oeste. 16 Además se ha supuesto un único tipo de seguidor en cada caso de forma que en dicha disposición todos los seguidores sean iguales. 3.1.2.3 Especificaciones de la ubicación del terreno. El espacio para la ubicación del terreno se ha limitado a las Comunidades Autónomas Españolas. Lo que la ubicación del terreno especifica es la latitud del lugar y por lo tanto, la posición del sol respecto de los seguidores. 3.2 Datos 3.2.1 Introducción de datos. Esta es la parte del programa orientada hacia El usuario y la única a la que el mismo tiene acceso. Aquí de lo que se trata es de definir la instalación para la cual se quieren obtener los datos de sombra, por lo que está dividido en tres partes: las dimensiones del seguidor, la distribución que se quiere estudiar y la ubicación de la misma. 3.2.1.1 Dimensiones del seguidor Las dimensiones que van a definir el seguidor que se quiere estudiar el ancho y alto de la parrilla de módulos, altura de la columna y ángulo máximo de inclinación. En la siguiente figura puede verse a qué corresponde cada una de estas dimensiones. La función que cumple cada una de ellas en el desarrollo del programa se explicará más adelante. 3.2.1.2 Distribución de los seguidores La distribución de los seguidores se introducirá mediante un plano de Autocad. Sin embargo, este plano deberá introducirse en la extensión *.dxf. Este es el Formato de intercambio de dibujos de Autocad (Drawing Interchange Format). Lo que esto supone de cara al programa que se ha desarrollado es que es un archivo de texto donde se va almacenando lo que Autocad va dibujando, de tal manera que, 17 leyendo dicho archivo, pueden obtenerse todos los datos asociados al dibujo. Para permitir que el programa pueda obtener los datos necesarios del plano, es necesario facilitar la siguiente información: el nombre de la capa correspondiente a la posición de los seguidores. La función de estos datos se explicará más adelante, en el apartado referente a la obtención de datos desde Autocad. 3.2.1.3 Ubicación de la instalación En este caso, lo que se requiere es la Comunidad Autónoma en la que va a realizarse la instalación. La función de este dato es la conocer la Latitud correspondiente para poder conocer con exactitud la posición del sol respecto a los seguidores en cada momento. La ventana de introducción de datos tiene la siguiente forma: 3.3 Algoritmos Previamente al desarrollo del código, se estudio la forma de llevar a cabo los cálculos que se debían realizar. La base del programa es el cálculo de las sombras que sobre un seguidor proyectan todos los de su alrededor; por lo tanto, la manera 18 en al que va a realizarse ese cálculo será la que defina la dinámica del programa y, en consecuencia, el desarrollo del programa. 3.3.1 Cálculos previos al código. La primera decisión que se debía tomar era la forma en la que se iba a realizar el cálculo de las sombras. El método elegido fue el de intersección de planos y la metodología la siguiente: Lo que se pretende es obtener la sombra que proyecta un seguidor sobre otro; la idea es que los límites de la sombra los definirán las sombras proyectadas por las aristas del seguidor. Por lo tanto, bastará calcular la intersección entre la sombra proyectada por dichas aritas y la superficie del seguidor sobre el que incide la sombra. Dichas rectas intersección estarán contenidas en la superficie del seguidor. Según lo expuesto, lo que hay que conseguir son dos rectas. Dado que una recta se pude definir como la intersección entre dos planos lo que tratamos es de hallar los dos planos que definan a cada una de las dos rectas. Por un lado, uno de los planos será el plano definido por el seguidor sobre el que se proyecta lo sombra. Como en ambos casos las rectas intersección están contenidas en la superficie de dicho seguidor, este plano será común a ambas. Los otros dos planos deberán contener la arista que se quiere proyectar y su sombra. Una de estas aristas será siempre la arista superior del seguidor. La otra, que será una de las aristas laterales, dependerá del lugar en el que se sitúe un seguidor respecto al otro y de la posición del sol respecto a ambos. Existen múltiples formas de definir un plano (tres puntos no alineados, una recta y un punto exterior a ella, dos rectas paralelas o dos rectas secantes); en este caso se ha optado por definirlo mediante tres puntos no alineados contenidos en él. A continuación se van a detallar los pasos a seguir para la obtención de los planos a partir de tres puntos no alineados, la intersección entre planos y, finalmente, la intersección entre dos líneas. 19 o primero habrá que definir los tres puntos que serán de la forma: R=( r1 , r2 , r3 ) S=( s1 , s 2 , s 3 ) T=( t1 , t 2 , t 3 ) Los elementos necesarios para lograr la ecuación del plano son dos vectores directores → y un punto. Los dos vectores → directores serán a ( a1 , a 2 , a 3 )y b ( b1 , b2 , b3 ) y el punto, s. Los vectores directores se calculan a través de los tres puntos ya definidos de la siguiente forma: a1 = s1 − t1 b1 = t1 − r1 a2 = s2 − t 2 b2 = t 2 − r2 a3 = s3 − t 3 b3 = t 3 − r3 La forma del plano que se ha utilizado es la reducida, resultado de igualar a cero el determinante formado por los dos vectores y el punto genérico X=(x, y, z) con el punto dado. De esta manera la ecuación del plano es det[(X-P) , u , v]=0 => Ax +By +Cz +D =0 Donde (A, B, C) es un vector perpendicular al plano y coincide con el producto vectorial de los vectores u y v. En el caso particular que estamos tratando, habrá que calcular tres planos: v1 x + v 2 y + v3 z + d = 0 w1 x + w2 y + w3 z + e = 0 20 u1 x + u 2 y + u 3 z + f = 0 Desarrollando el determinante anterior, obtenemos: v1 = (a 2 * b3 ) − (a3 − b2 ) v 2 = −((a1 * b3 ) − (a3 − b1 )) v3 = (a1 * b2 ) − (a 2 − b1 ) d = − s1 * v1 − s 2 * v 2 − s 3 * v3 Este plano será el común a ambas rectas. Los valores de los otros dos planos se hallarán de la misma forma que el anterior sustituyendo las v y la d por lo que corresponda. Por lo tanto, las dos rectas intersección vendrán definidas por los planos: r1: v1 x + v 2 y + v3 z + d = 0 w1 x + w2 y + w3 z + e = 0 r2: v1 x + v 2 y + v3 z + d = 0 u1 x + u 2 y + u 3 z + f = 0 De donde, operando obtenemos las siguientes rectas: ra1 = v1 − v3 * w1 w3 rb1 = v 2 − v3 * w2 w3 ra 2 = u1 − u 3 * w1 w3 rb2 = u 2 − u 3 * w2 w3 rc1 = d − v3 * e w3 rc 2 = f − u3 * e w3 Y por lo tanto las coordenadas X e Y del punto de intersección de ambas rectas será: 21 rb1 * rc 2 − rc1 rb 2 X = rb1 * ra 2 ra1 − rb 2 Y =− ( ra 2 * X ) + rc 2 rb 2 En el caso del plano definido por el seguidor, bastará con utilizar tres de los cuatro extremos del mismo y así que dará perfectamente definido el mismo. Para el caso de los otros dos planos, se ha optado por utilizar los dos puntos que corresponden al extremo de la arista que se deba emplear y la proyección de la sombra de uno de ellos sobre el suelo. Una vez definida la metodología que se va a seguir, hay que ver la manera de llegar hasta ella. 3.3.1.1 Ejes fijos y ejes solidarios al seguidor. El primer paso era definir unos ejes que sirvieran como base de coordenadas para poder definir los puntos, los planos y todo lo necesario para hallar las sombras. Definir los ejes fijos es bastante sencillo. Como una de las bases de todos estos cálculos es el movimiento del sol el cual se define a través de los ejes NorteSur y Este-Oeste parece bastante lógico utilizar estos mismos ejes como ejes fijos. Además, el tipo de instalaciones que se están estudiando, las huertas solares conectadas a red, se suele utilizar un marco de implantación rectangular según esos mismos ejes. Por lo tanto adoptando los ejes N-S, E-O como fijos se facilita considerablemente el trabajo. Hay que tener en cuenta que el tipo de seguidores para los que se está diseñando el programa, son seguidores con seguimiento de dos ejes. Esto significa que en todo momento permanecen perpendiculares a los rayos del sol. Como la posición del sol se define mediante dos ángulos (Azimut solar,ψ , y Altura solar, α ), la posición del seguidor respecto de los ejes fijos también estará definida por esos dos ángulos. Por lo tanto, resulta muy complicado proyectar cualquier punto del 22 seguidor directamente sobre los ejes fijos. Para facilitar el trabajo, se han utilizado unos ejes solidarios al seguidor tales que su posición respecto a los ejes fijos vendrá definida por el Azimut. Como puede apreciarse en la figura(num de la figura) el sentido positivo del eje x se ha hecho coincidir con el Oeste y el sentido positivo del eje y con el Sur. La razón por la que se ha elegido el Sur como el sentido positivo de la y se debe al Azimut que, como se ha comentado anteriormente, toma como origen el Sur. A los ejes solidarios al seguidor de ahora en adelante se les llamará ejes locales y a los ejes fijos, ejes globales de tal forma que cualquier variable con subíndice L estará en ejes locales y lo mismo ocurrirá con el subíndice G. Las ecuaciones que relacionarán los ejes locales con los globales serán los siguientes: xG = x L cosψ − y L senψ yG = x L senψ + y L cosψ 3.3.1.2 Coordenadas de un seguidor genérico El siguiente paso es definir las coordenadas de los extremos del seguidor en los ejes locales y globales. Para ello se utiliza un seguidor genérico de tal forma que el eje de coordenadas se sitúe en la base del mismo. La numeración de los extremos del seguidor va a ser la siguiente (en la figura se representa un momento en el que el Azimut solar es cero): 23 Una vez numerados los extremos del seguidor genérico, queda definir el valor de las coordenadas de esos cuatro en ejes locales para unos valores de Altura solar y Azimut solar igualmente genéricos. Para definir dichas coordenadas habrá que tener en cuenta que la base de la parrilla de módulos se mantiene en todo momento paralela al eje X L lo que implica que la coordenada XL de los cuatro extremos del seguidor se mantendrá invariable; independientemente de los valores que adopten las variables Altura y Azimut solar. Por lo tanto las coordenadas X L de los cuatro extremos del seguidor valdrán: base 2 base =− 2 x L1 = x L 2 = x L3 = x L 4 En el caso de la coordenada Y L , es un poco más complicado. De las variables referentes a las dimensiones del seguidor, en la que habrá que fijarse es en la altura de la parrilla de los módulos; sin embargo, en este caso, el valor de la proyección dependerá del ángulo de inclinación del seguidor. Dicho ángulo de inclinación viene definido por la Altura solar o, más directamente, por su complemento, el Ángulo cenital. 24 Antes de proceder a escribir las ecuaciones correspondientes falta determinar un último detalle. Puesto que los ejes locales son solidarios al seguidor y giran junto con él, los extremos 1 y 4 tendrán siempre un valor en coordenada y local positivo, mientras que los extremos 2 y 3 serán siempre negativos. Por todo lo expuesto hasta ahora y dada la simetría del seguidor tanto respecto del eje X L como del Y L , el valor absoluto de la coordenada Y L de los cuatro extremos del seguidor será el mismo. Exactamente lo mismo ocurre en el caso de los valores de la coordenada X L . altura cos θ 2 altura =− cos θ 2 y L1 = y L 4 = y L 2 = y L3 Finalmente queda por ver el valor de z para los cuatro extremos del seguidor. Como ya se ha comentado el eje z no varía de ejes locales a globales por lo que no hay necesidad de hacer distinciones. Aquí es donde entra en juego la Altura de la columna del seguidor. Dicha altura corresponde a la distancia existente entre el suelo y el centro del seguidor. Lo que hay que determinar es la altura de los extremos del seguidor en cualquier momento. Dado el tipo de movimiento que realiza el seguidor, manteniéndose en todo momento perpendicular a los rayos del sol, cuando el seguidor esté inclinado los extremos 1 y 4 se mantendrán siempre a una altura inferior que le de los extremos 2 y 3. Por lo tanto, excepto en el caso en que el seguidor esté totalmente paralelo al suelo o lo que es lo mismo, totalmente horizontal (bastante improbable), la altura de los extremos 1 y 4 será inferior a la de la columna del seguidor y la altura de los extremos 2 y 3, superior. Para el cálculo de estos datos será necesario conocer tanto la altura de la columna del seguidor como la altura de la parrilla de los módulos y el valor del Ángulo cenital: 25 Z L1 = Z L 4 = h − altura * sen(θ ) 2 Z L 2 = Z L3 = h + altura * sen(θ ) 2 Dado que los cuatro extremos del seguidor genérico ya están totalmente definidos para los ejes locales y que su adaptación a los ejes globales es inmediata a través del Azimut, la obtención del primero de los planos necesario para el cálculo de la sombra ya queda resuelto. 3.3.1.3 Proyección de la sombra Una vez que las coordenadas de los extremos ya son conocidas en todo momento, se puede proceder a calcular la proyección de la sombra de dichos extremos. La definición de estos datos permitirá, finalmente, obtener las ecuaciones de los dos planos que quedaban por calcular en la actividad que nos ocupa; el cálculo de la sombra. Como ya se ha comentado en el capítulo 1, en un instante en el que el Sol se encuentra en una posición definida por su azimut y su altura, la longitud sobre el suelo horizontal de la sombra de un objeto de altura h será: l= h tan(α ) Esta longitud está calculada sobre el eje y local. Concretamente, dado que el sol se encuentra en todo momento situado en el eje y positivo, esta longitud será siempre negativa en el eje y local. De lo expuesto se deduce que la sombra sólo afectará a la coordenada y local de los extremos, quedando de la siguiente manera: altura cos θ − d1 2 altura =− cos θ − d 2 2 y L1 = y L 4 = y L 2 = y L3 26 Donde d1 y d2 corresponde al valor de la longitud de la sombra. Para el cálculo de estas longitudes habrá que utilizar la altura de los extremos del panel; es decir, la coordenada z correspondiente a cada extremo: d1 = h1 / tan α d 2 = h2 / tan α De tal manera que: h1 = Z L1 = Z L 4 = h − altura * sen(θ ) 2 h2 = Z L 2 = Z L3 = h + altura * sen(θ ) 2 Concluido el cálculo de las coordenadas de la sombra de los extremos del seguidor en ejes locales, al igual que sucedía con las coordenadas de dichos extremos, la proyección de éstas sobre los ejes globales es inmediata sabiendo el azimut solar. 3.3.1.4 Calculo de sombra sobre un seguidor genérico. Finalmente, para definir los planos cuya intersección será la sombra proyectada de un seguidor sobre otro, solo queda decidir en cada ocasión cuál de las aristas laterales será la que haya que tener en cuenta. La solución planteada es la siguiente: A un seguidor cualquiera colocado en una huerta solar, le darán sombra todos los seguidores que tenga alrededor. En general, se supondrá que el seguidor está totalmente rodeado por otros seguidores. Como el criterio que se utiliza para la colocación de los mismos es la de ordenarlos en filas y columnas, en el caso de un seguidor que esté totalmente rodeado la disposición será la siguiente: 27 El seguidor genérico sobre el que se proyectarán las sombras es el del centro, el rayado. La numeración de la figura es la que se va a seguir en el desarrollo del programa y en este apartado va a utilizarse para definir en cada caso los planos que formarán parte del cálculo. Básicamente, lo que determinará los planos a utilizar será la posición de cada uno de los ocho seguidores respecto del central en cada momento; en definitiva, el azimut solar. Se estudia cada caso por separado. Al tratarse de planos infinitos, excepto que los tres sean paralelos, siempre habrá intersecciones entre unos y otros; lo cual no significa que un seguidor esté proyectando sombra sobre otro. Este hecho implica que debe especificarse en qué momento se considera qué la sombra de uno se está proyectando sobre el otro y en qué momento no. El caso más fácil es el común a todos; es decir, el de la intersección que forman los planos definidos por el seguidor genérico y el de la sombra de la arista superior del panel cuya sombra se esté estudiando. Dado que esta arista es siempre la 2-3, los planos serán los formados por los puntos: o 1 , 2 y 3 globales del seguidor genérico. o 2 y 3 del seguidor de la sombra junto con la proyección de la sombra del punto 3. Para obtener las coordenadas en ejes globales de los puntos 2 y 3 (y en general de los cuatro extremos del seguidor) basta sumarle a las coordenadas globales de esos mismos puntos del seguidor genérico, la distancia entre el seguidor que estemos estudiando y el anterior; es decir, si S x y Sy es la 28 separación entre el seguidor genérico y unos de los ocho seguidores que le rodean, las coordenadas globales de este último serán: X G = X G genérico + S x YG = YG genérico + S Y Una vez obtenida la recta intersección entre estos dos planos, habrá que comprobar que se encuentre por encima de la arista inferior del seguidor, en caso contrario la sombra no incidirá sobre el seguidor genérico. La altura de la recta intersección entre los dos planos será la siguiente: (v1 − Z recta = − w1 * v 2 e * v2 ) * X + (d − ) w2 w2 w *v v3 − 3 2 w2 Donde el valor de la x será el correspondiente al valor de la coordenada x en ejes globales del extremo 1 del seguidor. Además habrá que comprobar que la sombra no se encuentra fuera de la superficie del seguidor, bien sea por la izquierda o por la derecha. La forma de obtener las coordenadas de los puntos que definen el plano de la sombra de la arista lateral es idéntica a la expuesta anteriormente. Por la forma en la que se va a calcular dicho plano o, más concretamente, la forma en la que se realiza la elección de la arista que define el plano, lo que habrá que comprobar es que las coordenadas x e y del punto de intersección de las dos líneas esté dentro de la superficie del seguidor genérico; es decir, dentro de los valores de x y de y de los extremos del seguidor en cada instante: X G1 > X > X G 4 YG1 > Y > YG 3 29 Cuando la X y la Y estén entre esos valores máximos y mínimos, uno de los ocho seguidores, el que se esté calculando, estará proyectando sombra sobre el seguidor genérico. 3.3.1.4.1 Seguidor nº1 El seguidor nº1 es el que se halla al Suroeste del seguidor que nos sirve de base. Como puede apreciarse en la figura, este seguidor proyectará sombra sobre el seguidor central a partir del mediodía solar. Por la manera en la que se han definido los ángulos, después del mediodía solar el azimut será negativo (a la hora de hablar de la posición solar, por convención, el azimut es negativo si se refiere a antes del mediodía y positivo después; sin embargo, dado el funcionamiento de los ángulos en un eje de coordenadas, negativo según el movimiento de las agujas del reloj, resulta más práctico utilizar el signo del azimut al contrario para definir la posición del eje local respecto del global). Además, para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut>-45ºÆ arista lateral 3-4 o Azimut<-45ºÆ arista lateral 1-2 o A partir de Azimut=-90º, no proyectará sombra. 3.3.1.4.2 Seguidor nº2 Este seguidor se encuentra al Oeste del seguidor que nos sirve de referencia. Como consta en la figura, este seguidor proyectará sombra sobre el seguidor central a partir del mediodía solar, cuando el azimut sea negativo. Además, para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut>-90ºÆ arista lateral 3-4 30 o Azimut<-90ºÆ arista lateral 1-2 o En este caso, la variable S Y valdrá cero. 3.3.1.4.3 Seguidor nº3 Este está al Noroeste del seguidor que nos sirve de referencia. El seguidor nº3 proyectará sombra sobre el seguidor central a partir del mediodía solar, cuando el azimut sea negativo y dada su ubicación, cuando el azimut sea menor que menos noventa grados. Además, para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut>-135ºÆ arista lateral 3-4 o Azimut<-135ºÆ arista lateral 1-2 o Sin embargo, teniendo en cuenta que el valor máximo del azimut está en torno a los 120º, la última opción no es necesario tenerla en cuneta. 3.3.1.4.4 Seguidor nº4 El seguidor nº4 está justo al norte del seguidor genérico. Por lo general, dado el movimiento del sol que se ha estudiado en capítulos anteriores, este seguidor no proyectará sombra sobre el genérico excepto en casos excepcionales en los que ambos seguidores estén muy próximo. Se ha decidido incluirlo por si en algún caso resulta interesante conocer su aportación. Según lo comentado, este seguidor cabe la posibilidad de que proyecte sombra por la mañana muy temprano o a última hora de la tarde y únicamente durante unos pocos días del verano. Por lo tanto habrá que diferenciar entre las dos posiciones comentadas, la que se refiere a la mañana (azimut positivo) y la de la tarde(azimut negativo). 31 o Azimut>0Æ arista lateral 3-4 o Azimut<0Æ arista lateral 1-2 o En este caso, la variable S X valdrá cero. 3.3.1.4.5 Seguidor nº5 Este seguidor se encuentra al Noreste del seguidor que nos sirve de referencia. Como consta en la figura, este seguidor proyectará sombra sobre el seguidor central antes del mediodía solar, cuando el azimut sea positivo. Los valores relevantes del azimut para el caso del seguidor nº5 son similares a los del seguidor nº3 teniendo en cuenta que en este último caso el azimut era negativo. Para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut< 135ºÆ arista lateral 1-2 o Azimut>135ºÆ arista lateral 3-4 o Como el azimut no superará el valor de 135º, bastará con usar como límite los 90º a partir de los cuales será cuando este seguidor comience a proyectar sombra. 3.3.1.4.6 Seguidor nº6 Este seguidor se encuentra al Este del seguidor que nos sirve de referencia. Como consta en la figura, este seguidor proyectará sombra sobre el seguidor central antes del mediodía solar, cuando el azimut sea positivo. Para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut>90ºÆ arista lateral 3-4 o Azimut<90ºÆ arista lateral 1-2 o En este caso, la variable S Y valdrá cero. 32 3.3.1.4.7 Seguidor nº7 Este seguidor se encuentra al Sureste del seguidor que nos sirve de referencia. Como consta en la figura, este seguidor proyectará sombra sobre el seguidor central antes del mediodía solar, cuando el azimut sea positivo. Los valores relevantes del azimut para el caso del seguidor nº7 son similares a los del seguidor nº1 teniendo en cuenta que en este último caso el azimut era negativo. Para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut< 45ºÆ arista lateral 1-2 o Azimut>45ºÆ arista lateral 3-4 3.3.1.4.8 Seguidor nº8 Este seguidor se encuentra al Sur del seguidor que nos sirve de referencia. La sombra de este seguidor se intersecará con el seguidor genérico en las horas cercanas al mediodía solar (tanto azimut positivo como negativo) y especialmente en invierno, cuando la sombra es más alargada. Para la elección de los planos que definen la sombra habrá que diferenciar dos posiciones: o Azimut>0ºÆ arista lateral 3-4 o Azimut<0ºÆ arista lateral 1-2 o En este caso, la variable S X valdrá cero. 33 3.3.2 Desarrollo del código 3.3.2.1 Obtención de datos desde un plano de Autocad Esta parte del programa se ha desarrollado para poder leer los datos de posición de cada uno de los seguidores según el plano indicado por el usuario y ordenarlos de tal forma que sean útiles para el resto del programa. Lo que se pretendía es obtener unas matrices con las coordenadas x, y z de cada uno de los seguidores de tal forma que la distribución de la matriz coincida con la de los seguidores sobre el plano. Es decir, de lo que se trata es de lo siguiente (va a ilustrarse con un ejemplo): En este caso se trata de una distribución de 6 seguidores dispuestos de la siguiente forma: Puesto que hay 3 coordenadas diferentes en x y otras 3 en y, la matriz resultante será de 3*3 lo que implica 9 posiciones; por lo tanto, aquellas en las que no hay seguidores serán 0. De esta manera puede asociarse muy fácilmente los datos de la matriz con los seguidores a los que corresponden. A continuación se verá paso a paso cada una de las instrucciones y su función hasta obtener las matrices finales anteriormente comentadas. For cont = 1 To Filas Do linea = Dibujo.readline j=j+1 If j > Filas Then Exit For End If Loop While StrComp(linea, "SEGUIDORES") <> 0 Do linea = Dibujo.readline j=j+1 Loop While StrComp(linea, " 10") <> 0 34 i=i+1 ReDim Preserve xDibujo(i) ReDim Preserve yDibujo(i) ReDim Preserve zDibujo(i) xDibujo(i) = Dibujo.readline Dibujo.skipline yDibujo(i) = Dibujo.readline Dibujo.skipline zDibujo(i) = Dibujo.readline j=j+5 Next Dibujo.Close Estas instrucciones del código lo que hacen es leer el archivo DXF asociado al plano indicado por el usuario. Para extraer del mismo los datos que necesita, utiliza el nombre de la capa asignada a los seguidores. Por lo tanto, la manera de trabajar es la siguiente: o Busca en el archivo de texto la palabra ENTITIES, momento a partir del cual comienza a dibujar. o Buscar en el archivo de texto la palabra que corresponde al nombre de los seguidores, por ejemplo, SEGUIDORES. o Cuando encuentra la palabra SEGUIDORES, sigue buscando hasta encontrar el “10” que corresponde a la coordenada x. o Una vez encontrado el 10, pasa a la siguiente línea que corresponde al valor de la coordenada x lo almacena en una matriz llamada xDibujo(). o Se salta la siguiente línea, que será un “20”, y almacena el valor que corresponde a la coordenada y en la matriz yDibujo(). o Se salta la siguiente línea, que será un “30”, y almacena el valor que corresponde a la coordenada z en la matriz zDibujo(). o Una vez hecho esto con todo el archivo, cierra el mismo. 35 o Para asegurarnos de que lee todas las líneas y evitar errores, en unas instrucciones anteriores, abre el archivo, lee el número de filas que tiene y lo vuelve a cerrar. Así se obtiene la variable “Filas” y mediante una instrucción de condición IF se asegura de no sobrepasar el número de filas total. A continuación se puede ver una parte del código de texto de DXF que corresponde al dibujo de un seguidor. Aquí pude verse más fácilmente el funcionamiento del programa. 0 INSERT 5 140 330 1F 100 AcDbEntity 8 SEGUIDORES Æ 62 5 100 AcDbBlockReference 2 A$C3C474A2B 10 Æ 100.0000 Æ 20 Æ 200.0000 Æ 30 Æ 714.0 Æ Encuentra SEGUIDORES y empieza buscar 10 Encuentra 10 Almacena el valor Se salta la línea Almacena el valor Se salta la línea Almacena el valor y vuelve a empezar a buscar SEGUIDORES siempre que no haya llegado al final del archivo. 0 INSERT … En el código DXF los valores “10”, “20” y “30” corresponden a las coordenadas “x”, “y” y “z” respectivamente. Las matrices obtenidas de esta forma presentan dos problemas; por un lado, el número de veces que el archivo DXF llama a “SEGUIDORES” es superior al número de seguidores que hay en plano, esto se debe a que antes de dibujarlos debe definir la capa, el color de la misma,… por lo que habrá que extraer de esas matrices los elementos realmente necesarios. 36 Por otro lado, dado que el archivo es de texto, los datos obtenidos son de tipo texto, habrá que pasarlos a un formato numérico para poder operar con ellos. Estas dos acciones se llevan a cabo en las siguientes instrucciones donde, como se ve, hace uso del dato introducido por el usuario en referencia al número de seguidores que sirve para saber cuales son los elementos necesarios de las matrices. For posicion = (i - (Numseguidores - 1)) To i ii = ii + 1 zSeg(ii) = Val(zDibujo(posicion)) xSeg(ii) = Val(xDibujo(posicion)) ySeg(ii) = Val(yDibujo(posicion)) Next La función Val(string) devuelve un valor numérico de la cadena(string) que se introduzca. A partir de aquí, lo que trata es de colocar los valores de “x”, “y” y “z” que se han extraído del dibujo en la matriz final que se ha comentado antes; de tal forma que sus posiciones coincidan con las del plano de forma visual. Algo que a priori parece bastante sencillo requiere bastantes operaciones para llevarse a cabo de forma satisfactoria. Parece claro que, para conseguir la coincidencia mencionada, son los valores de la “x” y la “y” combinados los que me definirán el lugar de cada dato en la matriz final. A continuación van a explicarse los pasos que se han llevado a cabo para conseguirlo. Con las instrucciones que vienen a continuación, lo que se logra es ordenar los datos de las “x” de mayor a menor: For j = 1 To Numseguidores compara = 0.1 For i = 1 To Numseguidores If xSeg(i) > compara Then compara = xSeg(i) 37 posicion = i End If Next ORDENX(j) = compara POSICIONX(j) = posicion xSeg(posicion) = 0 Next Su forma de trabajar es la siguiente: o Revisa toda la matriz buscando el valor más alto. o Cuando lo encuentra, introduce ese valor en una nueva matriz denominada ORDENX() y lo pone a cero en la matriz original, de forma q pasa a ser el más pequeño. o Además, memoriza la posición que ocupaba ese elemento en la matriz original en una matriz denominada POSICIONX(); de esta manera, más adelante, se podrá relacionar cada valor de “x” con los de “y” y “z” que le correspondan. o Repite esta operación hasta que todos los elementos de la matriz original sean iguales a cero; momento en el que acaba. Una vez ordenadas las coordenadas x, se procede a ordenar las coordenadas y. Las instrucciones son muy similares a las anteriores cambiando xSeg(), ORDENX() y POSICIONX() por ySeg(), ORDENY() y POSICIONY() . Por lo tanto la forma de trabajar es casi idéntica. Por lo tanto, en este punto del programa ya tenemos las coordenadas de x y de y de los seguidores ordenadas de mayor a menor. A continuación se procede a calcular las dimensiones de la matriz final. Para calcular dichas dimensiones se verá cuántos valores diferentes de x y de y hay en las matrices correspondientes. En las instrucciones que siguen se lleva a cabo esta operación y la forma de operar es la siguiente: 38 xSeg() = ORDENX() For j = 1 To Numseguidores If xSeg(j) <> 0 Then compara = xSeg(j) ii = ii + 1 For i = 1 To Numseguidores If xSeg(i) = compara Then xSeg(i) = 0 End If Next End I Next o Utilizando la matriz de elementos ordenados de mayor a menor, coge el primer valor de x de la misma y cuenta 1. o A continuación compara todos los valores de la matriz con el anterior y pone a cero todos los que son iguales a él. o Una vez revisada toda la matriz, coge el siguiente valor distinto de cero y vuelve a empezar. o Cuando todos los valores de la matriz sean cero finaliza. o Al acabar, el valor de ii será el que nos indique la primera dimensión de la matriz final. Para obtener la segunda dimensión de dicha matriz, bastará con realizar la misma operación anterior con la matriz de elementos ordenados de mayor a menor correspondientes a la coordenada y. De aquí obtendremos el valor jj; por lo tanto, la matriz final será de orden ii*jj. Ahora falta por determinar el lugar que va a de ocupar cada elemento. La opción que se escogido para realizar esta operación es la siguiente: 39 o Por un lado, asignar el valor de la primera dimensión correspondiente a cada elemento mediante su valor de x de tal forma que los que vayan en la primera fila serán aquellos cuya x corresponda con el valor mayor, los de la segunda fila aquellos con la x inmediatamente inferior al valor mayor… así hasta llegar al valor más pequeño. o Por otro lado, asignar el valor de la segunda dimensión repitiendo la operación anterior con la y. o Por último, utilizando lo anterior y relacionando los datos a través de las matrices de posición ya almacenadas, hacer tres matrices de dimensiones ii*jj, una para cada coordenada, colocando cada elemento en el lugar que le corresponde. A continuación se explican cada uno de los procedimientos según el código correspondiente: For i = 1 To Numseguidores If xSeg(i) <> 0 Then b=b+1 compara = xSeg(i) For j = 1 To Numseguidores If xSeg(j) = compara Then a = POSICIONX(j) posx(a) = b xSeg(j) = 0 End If Next End If En este primer procedimiento lo que se hace es asignar a cada uno de los elementos, a través de la x, el subíndice de la primera dimensión que le corresponde. Funciona de la siguiente manera. 40 o Utilizando nuevamente la matriz con los elementos ordenados, coge el primer elemento y le asigna el subíndice 1. Esta asignación la realiza a través de la posición que ocupaba en la matriz original. o Compara el resto de elementos de la matriz con ese primero y a los que son iguales a él les asigna el subíndice 1 y los pone a 0. o Cuando no hay más elementos iguales a ese primero, pasa al siguiente elemento distinto de cero, corresponderá con el de valor inmediatamente inferior al primero y repite desde el segundo paso. o En el momento en el que todos los elementos que quedan sean igual a cero, acaba el procedimiento. Al acabar este procedimiento se habrá creado una nueva matriz que relaciona las posiciones de los elementos en las matrices originales (las obtenidas del archivo de Autocad) con los subíndices de la primera dimensión que les correspondan. Para hallar el subíndice de la segunda dimensión, el procedimiento será muy similar al anterior utilizando las coordenadas y en lugar de las x. Finalmente, lo único que queda por hacer es crear tres matrices de dimensiones ii*jj colocando en cada una de las posiciones las coordenadas correspondientes al seguidor que en el plano ocupa ese lugar. El procedimiento es el siguiente: For i = 1 To Numseguidores For j = 1 To Numseguidores If POSICIONX(j) = i Then a = posx(i) b = posy(i) c = POSICIONX(j) PoscSegX1(a, b) = XSEGUIDOR(c) PoscSegY1(a, b) = YSEGUIDOR(c) PoscSegZ1(a, b) = zSeg(c) End If 41 Next Next o Para cada posición de la matriz inicial, coge el subíndice de la primera dimensión(a) que la matriz pertinente le indica, coge el subíndice de la segunda dimensión(b) que la matriz pertinente le indica y coloca los elementos “x”, “y” y “z” pertenecientes a dicha posición y los coloca en otra matriz en el lugar(a,b). Finalmente, se realiza un último retoque a las matrices finales con el único objeto de facilitar su uso posteriormente. Como los datos se han ordenado de mayor a menor, la posición (1,1) la ocupará el seguidor más alejado del origen; es decir, el que tenga los valores más altos de x y de y. Resulta mucho más útil que sea al contrario, que el seguidor que ocupe la posición (1,1) sea aquel cuyos x e y sean los menores. Este último paso lo realiza el siguiente procedimiento: For a = ii To 1 Step -1 i=i+1 For b = jj To 1 Step -1 j=j+1 PoscSegX(i, j) = PoscSegX1(a, b) PoscSegY(i, j) = PoscSegY1(a, b) PoscSegZ(i, j) = PoscSegZ1(a, b) Next j=0 Next 3.3.2.2 Procesamiento de los datos En el procesamiento de datos se llevan a cabo todas las operaciones necesarias para, a partir de los datos introducidos por el usuario obtener los resultados finales; aquellos que aparecerán en la tabla de Excel. 42 Hasta el momento lo que se ha hecho ha sido adaptar los datos introducidos de tal manera que puedan ser empleados en esta sección pero no se ha operado con ellos. 3.3.2.2.1 El movimiento del Sol Puesto que la finalidad de este programa es obtener las sombras que proyectan unos seguidores sobre otros en una huerta solar, el primer paso será estudiar el movimiento del Sol. Lo que se pretende es conocer la posición del Sol respecto de cada uno de los seguidores en cada momento; de esta forma podremos saber cada uno de ellos la sombra que proyecta y, por lo tanto, la que reciben los demás. 3.3.2.2.1.1 La Latitud La Latitud es el único dato introducido por el usuario que queda por adaptar, pero su adaptación es más directa que las anteriores. Como ya se ha comentado anteriormente, este dato es introducido a través de la Comunidad Autónoma en la que se ubica la instalación. Obviamente este no es un dato numérico con el que pueda operarse pero sí tiene uno asociado. Ésta asociación se realiza mediante un “intercambio dinámico de datos” entre Visual Basic y Excel. Se parte de una tabla realizada en Excel en la que para cada Comunidad Autónoma se encuentra el correspondiente valor de la Latitud; de esta manera, cuando al programa se le introduce el dato de la Comunidad, Visual Basic acude a la tabla correspondiente de Excel y compara el dato introducido con los de la tabla. Una vez que encuentra el que coincide recoge el valor de la latitud de tal forma que ya puede ser usado por el programa. Para llevar a acabo este intercambio de datos, Visual Basic debe abrir el archivo de Excel en el que se encuentra la tabla que relaciona cada Comunidad Autónoma con la Latitud que le corresponde. Dicha tabla coincide con la siguiente: Altitud(m) Alava Latitud(º) 542 Longitud(º) 42,9 2.7W 43 Albacete 686 39 1.8W Alicante 7 38,4 0.5W Almería 65 36,9 2.4W Asturias 232 43,4 5.8W Avila 1126 40,7 4.9W Badajoz 186 38,9 7.0W Baleares 28 39,6 2.6E Barcelona 95 41,1 2.2E Burgos 929 42,3 3.7W Cáceres 459 39,5 6.4W Cádiz 28 36,5 6.3W Cantabria 69 43,5 3.8W Castellón 27 40 0 Ceuta 206 35,9 5.3W Ciudad Real 628 39 3.9W Córdoba 128 37,9 4.8W 54 43,4 8.4W Cuenca 949 40,1 2.1W Gerona 95 42 2.7E Granada 775 37,2 3.7W Guadalajara 685 40,6 3.2W Guipuzcoa 181 43,3 2.0W Huelva 4 37,3 6.9W Huesca 488 42,1 0.4W Jaén 586 37,8 3.8W León 908 42,6 5.6W Lérida 323 41,7 1.2E Lugo 465 43 7.6W Madrid 667 40,4 3.7W Málaga 40 36,7 4.4W Melilla 47 35,3 3.0W Murcia 42 38 1.1W Navarra 449 42,8 1.6W Orense 139 42,3 7.8W Palencia 734 42 4.5W Las Palmas 6 28,2 15.4W Pontevedra 19 42,4 8.6W La Rioja 380 42,5 2.4W Salamanca 803 41 5.6W La Coruña Sta. Cruz de Tenerife Segovia Sevilla Soria Tarragona 37 28,5 16.2 1002 41 4.1W 30 37,4 6.0W 1063 41,8 2.5W 60 41,1 1.2E Teruel 915 40,4 1.1W Toledo 540 39,9 4.0W 0.4W Valencia Valladolid Vizcaya 10 39,5 694 41,7 4.7W 32 43,3 3.0W Zamora 649 41,5 5.7W Zaragoza 200 41,7 0.9W . 44 El procedimiento asociado a dicho intercambio de datos es el siguiente: For Fila = 72 To 123 Latitud.LinkMode = 0 Latitud.LinkTopic = "Excel|Hoja1" Latitud.LinkItem = "F" & Fila & "C1" Latitud.LinkMode = 1 ColumnaA = "F" & CStr(Fila) & "C1" Latitud.LinkItem = ColumnaA If Left(Latitud.Text, Len(cmbComunidad)) = cmbComunidad Then Latitud.LinkMode = 0 Latitud.LinkTopic = "Excel|Hoja1" Latitud.LinkItem = "F" & Fila & "C3" Latitud.LinkMode = 1 ColumnaA = "F" & CStr(Fila) & "C3" Latitud.LinkItem = ColumnaA Exit For End If Next L = (Latitud.Text) * PI / 180 Donde el primer bloque busca en la primera columna, la correspondiente a las Comunidades Autónomas, la que coincide con la seleccionada; mientras que en el segundo bloque, una vez encontrada la Comunidad deseada, Obtiene de la tercera columna el valor de la Latitud que le corresponde y la asigna a una caja de texto. Es a través de dicho texto que se le asigna a la variable L. Puede comprobarse como, al tratarse de un valor que viene dado en grados, al asignarlo a la variable L, se hace uso de π 180 para pasarlo a radianes. 3.3.2.2.1.2 La posición del sol Una vez obtenida la latitud, se puede conocer la posición del Sol para cada día del año en cualquier momento del día. Dada la finalidad 45 de estos cálculos se ha obtenido la posición del Sol para cada día del año y para cada hora del día; con intervalos de media hora. Las expresiones utilizadas con este fin son las siguientes: δ = 23,45º sen (0,973 N − 77,84) senα = cos L cos δ cos ω + senLsenδ senψ = cos δsenω / cos α cosψ = ( senLsen α − senδ ) /(cos L cos α ) θ = 90º −α Donde: δ = Declinación solar N = Número de orden del día en el año( N=1 para el 1 de enero, N=365 para el 31 de diciembre) α = Altura solar L= Latitud del lugar ω = ángulo horario 46 ψ = Azimut solar θ = Ángulo cenital El primer detalle a tener en cuenta a la hora de realizar el cálculo de estas variables en Visual Basic es que éste trabaja en radianes por lo que será necesario adaptar las expresiones anteriores. En el caso de la declinación solar, primero se calcula 0,973*N77,84. Este dato, tal y como está calculado, se obtiene en grados centígrados por lo que habrá que pasarlo a radianes. Además, tal y como se indica, el factor por el que debe multiplicarse para obtener la declinación solar también está en grados. Una vez realizados estas operaciones puede procederse al cálculo de la declinación solar, que como puede apreciarse únicamente depende del día del año. Para poder obtener el resto de variables es necesario realizar otros ajustes. Por un lado, la latitud está, nuevamente, en grados centígrados por lo que se debe ajustar a radianes. El valor del ángulo horario en grados coincide con el número de horas de diferencia entre el instante considerado y el mediodía solar, multiplicado por 15 de tal forma que el ángulo horario sea positivo por la mañana. Este valor también debe ser adaptado a radianes. Por último, para el caso del ángulo cenital, dado que es el complemento de la altura solar, habrá que sustituir los 90º por su equivalente en radianes: π /2 El cálculo de estos datos se realiza mediante dos funciones: CalculoAngulos1 y CalculoAngulos2. La llamada a estas dos funciones 47 debe realizarse indicando como variables tanto el día como la hora del día de la que se quiere obtener los datos. Por definición, la Altura solar es el ángulo que forma el rayo (recta que va desde el centro del disco solar hasta el punto considerado) con el plano horizontal que pasa por el punto de observación. Dada la definición y como puede observarse en la figura, la Altura solar en ningún momento será mayor a 90º, dado que su posición respecto de los ejes Norte-Sur Este-Oeste vendrá definido por el Azimut solar por lo que en este caso no será necesario hacer más consideraciones. Como se ha comentado, es el Azimut solar el que define la posición del sol respecto a los dos ejes por lo que es necesario tener en cuenta que puede hallarse en cualquiera de los cuatro cuadrantes. Es por esta razón que para su cálculo se utilizan dos ecuaciones, una para el seno y otra para el coseno de forma que quede completamente definido. Para obtener el dato del Azimut se procede de la siguiente manera: o Realizar el cálculo del seno y el coseno del Azimut solar. o Si: Seno >0 , Coseno >0 --Æ ángulo del 1º cuadrante, cálculo del valor del Azimut solar mediante el ArcoSeno o ArcoCoseno. o Si: Seno >0 , Coseno < 0 --Æ ángulo del 2º cuadrante, cálculo del valor del Azimut solar mediante el ArcoCoseno. o Si: Seno <0 , Coseno >0 --Æ ángulo del 4º cuadrante, cálculo del valor del Azimut solar mediante el ArcoSeno. o Si: Seno <o , Coseno <0 --Æ ángulo del 3º cuadrante, no es posible realizar el cálculo del Azimut solar de forma directa por lo que se ha resuelto calcular el valor del ángulo correspondiente al 4º cuadrante mediante el ArcoSeno y restárselo a -180º. 48 Una vez obtenidas las variables referentes a la posición del sol para cada hora del día y para cada día del año y haciendo uso de los valores introducidos por el usuario referentes al tamaño del seguidor, base y altura de la parrilla de módulos, altura de la columna y tamaño del terreno en el que va a instalarse la huerta solar, se puede proceder a realizar los cálculos necesarios para la obtención de las separaciones óptimas entre filas y columnas de seguidores. En lo sucesivo, cuando sea necesario utilizar estos datos nos referiremos a ellos de la siguiente manera: o Base: base de la parrilla de módulos o Altura: altura de la parrilla de módulos o h: altura de la columna A continuación se verá el extracto de código perteneciente a cada una de las funciones. Por un lado la función CalculoAngulos1 permite calcular la altura solar para el día y la hora del día requeridos de la siguiente forma: Function CalculoAngulos1(N As Integer, Hora As Single) XD = (0.973 * N - 77.84) * PI / 180 DecliRad(N) = (23.45 * PI / 180) * Sin(XD) wGrad = Abs(12 - Hora) * 15 w = wGrad * PI / 180 Desviacion = 0 49 X1 = Cos(L) * Cos(DecliRad(N)) * Cos(w) + Sin(L) * Sin(DecliRad(N)) If X1 < 0 Then CalculoAngulos1 = 0 Exit Function Else If -X1 * X1 + 1 = 0 Then AlturaRad(N, Hora) = PI / 2 Else AlturaRad(N, Hora) = Atn(X1 / Sqr(-X1 * X1 + 1)) 'Arcoseno End If End If CalculoAngulos1 = AlturaRad(N, Hora) End Function Como ya se comentó anteriormente, el primer cálculo que debe realizarse es el de la Declinación solar que únicamente depende del día del año para el que se quiera calcular. A continuación, se cambia la hora por su homólogo en grados como ya se explicó anteriormente. A lo largo del código también puede apreciarse que se lleva a cabo siempre que es necesario la conversión de grados a radianes. Por último cabe comentar que Visual Basic desconoce las funciones ArcoSeno y ArcoCoseno pero sí permite realizar la función ArcoTangente. Es por eso que a través de esta última se calcula el valor de las dos anteriores, según las fórmulas: ArcoSeno( x) = ArcoTangente( ArcoCoseno( x) = ArcoTangente( x (− x * x) + 1 −x (− x * x) + 1 ) ) + 2 * Ar cot angente(1) Por otro lado, la función CalculoAngulos2 permite calcular el Azimut solar para el día y la hora del día requeridos de la siguiente manera: Function CalculoAngulos2(N As Integer, Hora As Single) 50 Altura = CalculoAngulos1(N, Hora) If Altura = 0 Then CalculoAngulos2 = 0 Exit Function Else X2 = Cos(DecliRad(N)) * Sin(w) / Cos(Altura) X3 = (Sin(L) * Sin(Altura) - Sin(DecliRad(N))) / (Cos(L) * Cos(Altura)) If X2 >= 0 Then If X3 > 0 Then '1er cuadrante If X2 = 1 Then AzimutRad(N, Hora) = PI / 2 Else AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) 'Arcoseno End If Else '2º cuadrante AzimutRad(N, Hora) = Atn(-X3 / Sqr(-X3 * X3 + 1)) + 2 * Atn(1) 'Arcocoseno End If ElseIf X3 > 0 Then '4º Cuadrante AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) 'Arcoseno Else '3º cuadrante If X2 = -1 Then AzimutRad(N, Hora) = -PI / 2 Else AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) - (PI / 2) 'Arcoseno End If End If End If If Hora <= 12 Then CalculoAngulos2 = AzimutRad(N, Hora) Else CalculoAngulos2 = -AzimutRad(N, Hora) End If En esta función hay varios aspectos a comentar. Para empezar, para calcular el Azimut solar es necesario conocer la Altura solar por lo que, al principio de la función se hace una llamada a la función correspondiente a la Altura que es CalculoAngulos1. Aquí puede apreciarse como para efectuar dicha llamada se deben adjuntar los datos de día y hora del día para los que se quiere conocer la Altura. 51 Una vez obtenido el valor de la altura, comprueba que éste no sea igual a cero; es decir, que no sea por la noche en cuyo caso no se hará ningún cálculo puesto que no habrá sombras. Siempre que la Altura sea diferente de cero, se procederá a realizar los cálculos propios del Azimut para lo cual se procederá teniendo en cuenta lo expuesto con anterioridad sobre los diferentes cuadrantes. Puede observarse como lo primero que hace es calcular el seno y el coseno del mismo ángulo con el fin de poderlo situar con exactitud y finalmente, dependiendo del cuadrante que le corresponda, se procede a su cálculo. Como último apunte, cabe resaltar que tal y como está hecho el cálculo el Azimut siempre saldrá positivo, independientemente de que se calcule para antes o después de las 12 del mediodía; momento en el que el Azimut es igual a cero, dado que coincide con el eje NorteSur, y por lo tanto implica un cambio de signo. Para corregir este defecto, se le adjunta un signo positivo o negativo dependiendo de la hora a la que se realice el cálculo. 3.3.2.2.2 Posición del seguidor Para realizar el cálculo de la sombra de un seguidor que incide sobre otro es imprescindible conocer la posición de cada uno de los seguidores. Puesto que en la instalación todos los seguidores serán iguales, bastará saber las coordenadas de uno genérico, que tomaremos como origen, y mediante las distancias entre seguidores podremos determinar las coordenadas de los extremos de cada uno de los seguidores. En el cálculo de las coordenadas de los extremos de los seguidores se utilizan los datos de entrada correspondientes a las dimensiones del seguidor: Base, Altura, h y el dato de entrada correspondiente al ángulo máximo de inclinación. El proceso de cálculo es el siguiente: primero calcular las coordenadas locales del seguidor, segundo convertirlas a globales. 52 Las coordenadas locales se calculan respecto a unos ejes solidarios al seguidor que giran con respecto a los ejes fijos definidos por las líneas Norte-Sur y Este-Oeste, un valor que equivale al azimut solar. Por lo tanto, la relación entre los ejes locales y los globales los define el Azimut solar. 3.3.2.2.2.1 Coordenadas locales del seguidor Como ya se ha comentado, las coordenadas correspondientes a las cuatro aristas del seguidor se calculan para un seguidor genérico y se supone el origen de coordenadas en la base del seguidor de tal forma que cuando el Azimut solar sea igual a cero y el seguidor esté totalmente paralelo al suelo, el seguidor, visto desde arriba, quede de la siguiente manera. Teniendo en cuenta la figura anterior es fácil observar que la proyección sobre el eje x solidario al seguidor será siempre la mitad del valor de la base con el signo que le corresponda. En el caso del eje y solidario al seguidor, el valor de la proyección dependerá de la inclinación del seguidor y, por lo tanto de la Altura solar. Además, para cada una de los cuatro extremos del seguidor, el signo de la proyección sobre esos mismos ejes será siempre el mismo. Por lo tanto, las ecuaciones de las proyecciones de los cuatro extremos del seguidor sobre los ejes solidarios al mismo serán de la forma: base 2 base x L3 = x L 4 = − 2 altura cos θ y L1 = y L 4 = 2 altura cos θ y L 2 = y L3 = − 2 x L1 = x L 2 = Finalmente, queda por ver el valor de la proyección sobre el eje z. Este valor será el mismo tanto en ejes locales como en globales puesto que el eje z no varía. La proyección de cada uno de los cuatro extremos sobre el eje z depende de la altura de la columna del seguidor, h, la altura de la 53 parrilla, altura, y el ángulo de inclinación del seguidor de tal manera que: Z L1 = Z L 4 = h − altura * cos( AlturaSeg ) 2 Z L 2 = Z L3 = h + altura * cos( AlturaSeg ) 2 En el programa, el cálculo de estas tres coordenadas para cada extremo de seguidor se realiza mediante tres funciones que son las siguientes: Function XLSeguidor(Punto As Integer) Select Case Punto Case 1, 2 XL = BaseP / 2 Case 3, 4 XL = -BaseP / 2 End Select XLSeguidor = XL End Function La llamada a esta función, a la que le corresponde el cálculo de la coordenada x local, debe realizarse indicando el número del extremo del que quiere saberse dicha coordenada. Lo que esta función hace es ver cuál es el punto para el que se le ha pedido la información y, según cual sea realizar una operación u otra; la que corresponda. Finalmente devuelve el valor requerido. Function YLSeguidor(N As Integer, Hora As Single, Punto As Integer, Sombra As Integer, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If AnguloNormalSeg = (PI / 2) - AlturaSeg If Sombra = 0 Then 54 Select Case Punto Case 1, 4 YL = AlturaP * Cos(AnguloNormalSeg) / 2 Case 2, 3 YL = -(AlturaP * Cos(AnguloNormalSeg) / 2) End Select ElseIf Sombra = 1 Then Select Case Punto Case 1, 4 YL = (AlturaP / 2) - DistanciaSombra1(N, Hora, h, AngMax) * Cos(AnguloNormalSeg) Case 2, 3 YL = -((AlturaP / 2) + DistanciaSombra2(N, Hora, h, AngMax)) * Cos(AnguloNormalSeg) End Select End If YLSeguidor = YL End Function Esta función, la correspondiente al cálculo de la coordenada y, es algo más complicada que la anterior. En primer lugar, la llamada a la misma ha de realizarse indicando muchas más variables para que el cálculo pueda llevarse a cabo. Por supuesto, debe indicarse el número del extremo para el que se desea obtener la información. Además, según lo expuesto anteriormente, el valor de la proyección sobre el eje y depende de otras variables como la Altura solar y el ángulo máximo de inclinación. Debido a que necesita calcular la Altura solar es por lo que deben indicársele el día y la hora del día en el que se está trabajando. También hay dos variables que se refieren al cálculo de la sombra que son la denominada Sombra, que será 1 o 0 según si se quiere calcular la sombra o no, y la h. Todo lo referente a estas dos variables y el papel que juegan se explicará en el apartado dedicado a las Sombras. El procedimiento que sigue esta función es el siguiente: o Calcular el valor de la Altura solar en ese instante para lo cual realiza una llamada a la función correspondiente, CalculoAngulos1. 55 o Comprueba que la Altura solar sea mayor que el ángulo de inclinación del seguidor. En caso de que no lo sea, el valor de la Altura del seguidor será igual al ángulo de inclinación máximo; sino, será igual a la Altura solar. o Calcula el Angulo Normal del seguidor. o Comprueba si debe calcular el valor de la sombra o no (El proceso que sigue en caso de que calcule la sombra se expondrá en el apartado de sombras). o En caso de que sea que no, según cuál sea el punto para el que debe realizar la operación, hace una operación u otra o Devuelve el valor requerido. Function ZLSeguidor(N As Integer, Hora As Single, Punto As Integer, h As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If Select Case Punto Case 1, 4 ZL = h - (AlturaP * Cos(AlturaSeg) / 2) Case 2, 3 ZL = h + (AlturaP * Cos(AlturaSeg) / 2) End Select ZLSeguidor = ZL End Function 56 Esta última función es la que se encarga de calcular la coordenada z de cada uno de los extremos del seguidor. Las variables que necesita para realizar su tarea son las mismas que las de la función anterior exceptuando las relacionadas con la sombra. La dinámica de trabajo de la función ZLSeguidor() es la siguiente: o Calcular el valor de la Altura solar en ese instante para lo cual realiza una llamada a la función correspondiente, CalculoAngulos1. o Comprueba que la Altura solar sea mayor que el ángulo de inclinación del seguidor. En caso de que no lo sea, el valor de la Altura del seguidor será igual al ángulo de inclinación máximo; sino, será igual a la Altura solar. o Dependiendo del punto para el que deba realizar el cálculo, realiza una operación u otra. o 3.3.2.2.2.2 Devuelve el valor requerido. Coordenadas globales del seguidor Para hallar las coordenadas globales del seguidor, basta proyectar las coordenadas locales ya calculadas sobre los ejes fijos según la relación: xG = x L cosψ − y L senψ y G = x L senψ + y L cosψ Para realizar esta transformación se ha definido una función denominada LocalesAGlobales() que es de la siguiente forma: Function LocalesAGlobales(N As Integer, Hora As Single, Coord As Integer, Punto As Integer, Sombra As Integer, h As Single, AngMax As Single) Azimut = CalculoAngulos2(N, Hora) If Coord = 1 Then 57 XL = XLSeguidor(Punto) YL = YLSeguidor(N, Hora, Punto, Sombra, h, AngMax) G = XL * Cos(Azimut) - YL * Sin(Azimut) ElseIf Coord = 2 Then XL = XLSeguidor(Punto) YL = YLSeguidor(N, Hora, Punto, Sombra, h, AngMax) G = XL * Sin(Azimut) + YL * Cos(Azimut) Else G = ZLSeguidor(N, Hora, Punto, h) End If LocalesAGlobales = G End Function La razón por la que cada vez las funciones dependen de mayor número de variables es que según avanza el desarrollo del programa, cada una de las funciones, a su vez, realiza llamadas a otras funciones y cada una de estas funciones requieren de sus propias variables. Esta función distingue entre las coordenadas x, y y z globales para realizar sus cálculos. A su vez, el cálculo de x o y dependerá de los valores de x e y locales, que deberán ser calculados. Por su parte, en el caso de que la coordenada global a calcular sea z, ésta será igual a la z local; según lo expuesto anteriormente. El funcionamiento de esta función es el siguiente: o Calcular el Azimut solar. o Comprobar qué coordenada global queremos obtener: x, y o z. o Según sea x o y, realizar las operaciones pertinentes. o En el caso de z, calcular el valor de la z local. o Devuelve el valor requerido. 58 3.3.2.2.3 Cálculo de la sombra Puesto que el programa ya está en condiciones de calcular las variables relacionadas con la posición del sol en cada momento, puede pasar a calcular la sombra que proyecta cada seguidor en cada uno de esos momentos. Para llevar a cabo estos cálculos es indispensable utilizar los datos referentes a las dimensiones del seguidor. Principalmente habrá que saber la altura de las cuatro esquinas del seguidor en cada momento para lo cual habrá que tener en cuenta la inclinación del mismo. Una vez obtenidas las longitudes de sombra, se puede obtener la proyección de dicha sombra tanto sobre la línea Norte-Sur como sobre la línea Este-Oeste. Estas dos líneas van a definir los ejes de coordenadas x e y. 3.3.2.2.3.1 Longitud de la sombra En un instante en que el Sol se encuentra en una posición definida por su azimut ψ y su altura α , la longitud sobre el suelo horizontal de la sombra de un objeto de altura h será h/tan α , y la proyección de dicha sombra sobre la línea Norte-Sur, trazada en el plano horizontal (meridiano del lugar), valdrá: d = h cosψ / tan α Utilizando esta expresión es posible hallar la longitud sobre el suelo horizontal de la sombra de los cuatro extremos del seguidor en cada momento para lo cual se debe tener en cuenta el ángulo de inclinación del seguidor. Dado que se trata de seguidores de dos ejes, éstos van a mantenerse en todo momento perpendiculares a los rayos del sol lo que implica que cuando el ángulo cenital valga ángulo de inclinación del seguidor con la horizontal valdrá θ, el θ. Mediante el ángulo de inclinación del seguidor, en cada momento se obtendrán dos alturas diferentes a tener en cuenta; las 59 correspondientes a la arista superior e inferior del seguidor que serán respectivamente: h1 = h − altura * sen(θ ) 2 h2 = h + altura * sen(θ ) 2 Por lo tanto se obtendrán dos longitudes sobre el suelo horizontal correspondientes a la sombra de la arista superior e inferior del seguidor: d1 = h1 / tan α d 2 = h2 / tan α El cálculo de estas dos distancias, o longitudes de sombra, se realizan mediante denominadas dos funciones, DistanciaSombra1 una para y cada distancia, DistanciaSombra2 respectivamente. Function DistanciaSombra1(N As Integer, Hora As Single, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If If Altura = 0 Then d1(N, Hora) = 0 Else h1(N, Hora) = h - (AlturaP * Sin((PI / 2) - AlturaSeg) / 2) d1(N, Hora) = h1(N, Hora) / Tan(Altura) End If DistanciaSombra1 = d1(N, Hora) 60 End Function Function DistanciaSombra2(N As Integer, Hora As Single, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If If Altura = 0 Then d2(N, Hora) = 0 Else h2(N, Hora) = h + (AlturaP * Sin((PI / 2) - AlturaSeg) / 2) d2(N, Hora) = h2(N, Hora) / Tan(Altura) End If DistanciaSombra2 = d2(N, Hora) End Function Lo que diferencia ambas funciones es la altura de los puntos para los que se está calculando la longitud de la sombra; puesto que la primera se refiere a la arista superior del seguidor y la segunda a la arista inferior. Para calcular dichas longitudes, como ya se ha comentado, hay que tener en cuenta la inclinación del seguidor. Según lo expuesto, al tratarse de seguidores con seguimiento a dos ejes, éstos se mantienen siempre perpendiculares a los rayos del sol; sin embargo, hay que tener en cuenta una limitación del sistema: los seguidores tienen un ángulo máximo de inclinación, a partir del cual dejarán de seguir al sol. Es por ello que resulta necesario distinguir entre dos ángulos diferentes cuando hablemos de la Altura; por un lado la Altura solar, calculada según la función correspondiente, y por otro lado el ángulo Altura del seguidor que coincidirá con la Altura solar siempre y cuando éste sea menor que el ángulo máximo de inclinación del seguidor. Cuando sea menor, el ángulo Altura del seguidor será el ángulo máximo de inclinación del mismo. Este ángulo máximo de inclinación es un dato de entrada que debe tenerse en cuenta a la hora de calcular la altura de las aristas en cada momento. 61 3.3.2.2.3.2 Coordenadas locales de la sombra Primero debemos definir el lugar exacto que los cuatro extremos del seguidor ocupan respecto a los ejes solidarios al mismo y sumarle la longitud de la sombra calculada. El origen de coordenadas se encuentra en la base del seguidor. Los ejes x e y globales o fijos coinciden con las líneas Norte-Sur y Este-Oeste como ya se ha comentado; el sentido positivo del eje x coincide con el Este y el del eje y con el Sur. Por su parte los ejes solaces o solidarios al seguidor son tales que cuando el Azimut sea cero, coincidan con los ejes globales. Por lo tanto, los cuatro extremos de la sombra del seguidor en ejes locales quedan: base 2 base x L3 = x L 4 = − 2 altura y L1 = y L 4 = cos θ − d1 2 altura y L 2 = y L3 = − cos θ − d 2 2 x L1 = x L 2 = De estas ecuaciones se deduce que en ejes locales la única coordenada que varía entre los extremos del seguidor y los extremos de la sombra del seguidor es la y. Por lo tanto, el cálculo de las coordenadas locales se realiza en tres funciones diferentes; una para el cálculo de la x, otra para el cálculo de la y y por último, una para el cálculo de la z. Estas funciones se denominan XLSeguidor, YLSeguidor y ZLSeguidor respectivamente. Las funciones XLSeguidor y ZlSeguidor ya han sido explicadas en el apartado referente a las coordenadas del seguidor (Apartado 1.3.2.1). Estas dos funciones sirven igualmente en el caso de las sombras puesto que en coordenadas locales, lo único que varía es el valor de la y. Dentro de la función para el cálculo de la y, YLSeguidor, hay dos partes; la que se refiere al calculo de la coordenada y del seguidor y aquella para el cálculo de la coordenada y de la sombra del seguidor. 62 En el apartado del cálculo de las coordenadas del seguidores se ha explicado el funcionamiento de esta función a excepción de la parte que concierne al cálculo de la sombra; es decir, cuando la variable Sombra tiene valor 1. A continuación se reproduce ésta última parte con el fin de que la explicación pueda ser más clara: ElseIf Sombra = 1 Then Select Case Punto Case 1, 4 YL = (AlturaP / 2) - DistanciaSombra1(N, Hora, h, AngMax) * Cos(AnguloNormalSeg) Case 2, 3 YL = -((AlturaP / 2) + DistanciaSombra2(N, Hora, h, AngMax)) * Cos(AnguloNormalSeg) End Select End If El funcionamiento es muy similar a los anteriores, según el extremo del que se quiera saber el valor, realiza las operaciones necesarias. La diferencia es que en este caso utiliza las funciones DistanciaSombra1() y DistanciaSombra2(). Es por esta razón que requiere las variables Angulo máximo de inclinación y h. 3.3.2.2.3.3 Coordenadas globales de la sombra Dentro del programa existe una función específica para la transformación de coordenadas locales en globales denominada LocalesAGlobales que ya ha sido expuesta en el apartado 1.3.2.2. Lo único que variará respecto a lo anterior es que en este caso la variable Sombra adoptará el valor 1. 63 3.3.2.2.4 Cálculo de las pérdidas por sombra. Una vez definidas todas las funciones que integran el programa, queda por ver cómo se realiza el cálculo del porcentaje de sombra que recibe cada seguir debido a los que le rodean. Puesto que este cálculo debe realizar para cada uno de los seguidores de la instalación y el dato quiere obtenerse mes a mes, los tres primeros bucles se encargan de eso. Los dos primeros lo que hacen es barrer las matrices obtenidas en la obtención de datos desde un plano de Autocad (Apartado 1.2) . Por lo tanto, cada uno de los seguidores vendrá definido por el lugar que ocupa en la matriz; de tal forma que, por ejemplo, el seguidor 1 tendrá las coordenadas (1,1); el seguidor 2 las coordenadas (1,2),… La dinámica que sigue el código es la siguiente; o se coloca en uno de los seguidores de la instalación, el (a,b) y memoriza sus datos en dos variables: XSEGFijo = PoscSegX(a, b) YSEGFijo = PoscSegY(a, b) Hasta que pase al siguiente seguidor de la instalación, estos dos datos serán los únicos que se mantengan invariables puesto que hacen referencia a la posición que el seguidor ocupa en el plano y por lo tanto le relaciona con los de alrededor. o A través de estas variables el programa comprueba que en esa posición realmente haya un seguidor, en caso contrario pasa directamente al siguiente puesto que no habrá seguidor sobre el que calcular las sombras. o En caso de que el seguidor exista, se le suma uno a una variable llamada “SeguidorNumero” cuya única función es facilitar la salida de datos al final del programa. SeguidorNumero = SeguidorNumero + 1 64 o Dado que la salida de datos se quiere realizar mes a mes, el programa va pasando por cada uno de ellos desde enero (1) hasta diciembre (12). Dependiendo del mes en el que esté, selecciona el número de días correspondientes al mismo. For Mes = 1 To 12 Select Case Mes Case 4, 6, 9, 11 FinMes = 30 Case 1, 3, 5, 7, 8, 10, 12 FinMes = 31 Case 2 FinMes = 28 End Select o Una vez posicionado en un mes, recorre el mes entero día a día. Dado que para el cálculo de los ángulos, y por lo tanto el de la mayoría de las variables es necesario saber el día del año para el que se quieren realizar los cálculos, cada vez que pasa por un nuevo día suma una unidad a la variable denominada Día. Dia = Dia + 1 o Las dos siguientes tareas que realiza son pasar por todos los seguidores que rodean al seguidor “fijo” (del 1 al 8 como ya se ha explicado más arriba) y recorrer todas las horas del día en intervalos de media hora. Llegados a este punto es cuando empieza a realizar los cálculos para determinar la sombra que proyectan los ocho seguidores de alrededor sobre el q esté estudiando. o Primero calcula el Azimut y la Altura llamando a las funciones respectivas. Estos dos datos van a servirle para comprobar varias condiciones a lo largo del procedimiento. 65 o Para empezar comprueba que no sea de noche mediante la Altura solar. En caso de que sí sea de noche, pone todos los cálculos a cero y pasa a la siguiente hora. o En caso de que sea de día continúa con el procedimiento. A partir de aquí, lo que hará es ir viendo en qué seguidor de los de alrededor al fijo está situado para realizar los cálculos respectivos a cada uno de ellos. Se analizará uno a uno cada uno de los casos para aclarar las diferencias existentes entre ellos. Los fundamentos de estas acciones ya han sido expuestos con anterioridad por lo que se tratarán escuetamente. 3.3.2.2.4.1 Seguidor nº1 Como puede apreciarse en el código, el seguidor número 1 está tratado en conjunto con el número 3. Esto se debe a que, aunque obviamente existen algunas diferencias, también comparten bastantes similitudes de cara al cálculo de sombras. La posición de ambos es oblicua respecto del seguidor “fijo” y en el caso de ambos, la separación respecto al anterior es positiva en el eje x o eje Este-Oeste. Además, ambos proyectarán sombra después del mediodía solar; es decir, después de las 12 en la hora solar por lo que el Azimut con el que trabajarán tendrá el mismo signo para ambos. Para ambos seguidores, si la coordenada a es igual a 1, no se realizará ningún cálculo y se pasará al siguiente puesto que el seguidor estará en la columna de la derecha y a su derecha no tendrá seguidores que le puedan hacer sombra. En el caso del seguidor número uno el desarrollo del programa será el siguiente: o Si el seguidor “fijo” está en la primera fila, b es igual a 1, no se realizará ningún cálculo y se pasará al siguiente puesto que no habrá ningún seguidor en la posición del seguidor 1. 66 o Si el Azimut es mayor que 90º, el seguidor uno no proyectará sombra sobre el seguidor “fijo”, por lo que tampoco se realizará ningún cálculo y se pasará al siguiente. o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor 1 cuyas coordenadas de la matriz de seguidores será: (a-1, b-1). sx = XSEGFijo -PoscSegX(a - 1, b - 1) sy = YSEGFijo -PoscSegY(a - 1, b - 1) o Nuevamente se debe comprobar que el seguidor de esa posición existe; en caso negativo, no se realiza ningún cálculo y se pasa al siguiente. Este paso se realiza para todos los seguidores en el procedimiento correspondiente a cada uno de ellos. o En caso de que dicho seguidor exista, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº1. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.4.2 Seguidor nº2 En el caso del seguidor número 2, el desarrollo del programa será el siguiente: o Si el seguidor “fijo” está en la primera columna; es decir, a es igual a 1, no se realizará ningún cálculo y se pasará al siguiente puesto que no existirá ningún seguidor en la posición del seguidor 2. 67 o En el caso de que a no sea igual a 1, se comprobará que existe un seguidor en la posición correspondiente al seguidor número dos en la matriz, cuyas coordenadas serán: (a-1, b). Si no existe, no se hace ningún calculo y se pasa al siguiente caso. o En el caso de que sí haya un seguidor en esa posición, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor 2 sx = XSEGFijo -PoscSegX(a - 1, b ) sy = YSEGFijo -PoscSegY(a - 1, b ) o Finalmente, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº2. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.4.3 Seguidor nº3 Como ya se ha comentado en el caso del seguidor nº1, estos dos son tratados juntos. Una vez realizadas las comprobaciones comunes a ambos que ya se han tratado en el apartado del seguidor nº1 (Apartado 1.3.4.1) se verá lo que difiere al seguidor nº3 del seguidor nº1. Como podrá comprobarse, llegados a este punto, todos los procedimientos son muy similares. Difieren únicamente en pequeños detalles esenciales sin embargo para el buen funcionamiento del programa. Es por ello que se intenta detallar minuciosamente. 68 o Si el seguidor “fijo” está en la última fila, b es igual a jj, no se realizará ningún cálculo y se pasará directamente al siguiente caso ya que no habrá posibilidad de que haya ningún seguidor en la posición del seguidor nº3. o Si el Azimut es menor que 90º, el seguidor 3 no proyectará sombra sobre el seguidor “fijo”, por lo que tampoco se realizará ningún cálculo y se pasará al siguiente. o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor 3 cuyas coordenadas de la matriz de seguidores será: (a-1, b+1). sx = XSEGFijo -PoscSegX(a - 1, b + 1) sy = YSEGFijo -PoscSegY(a - 1, b +1) o Nuevamente se debe comprobar que el seguidor de esa posición existe; en caso negativo, no se realiza ningún cálculo y se pasa al siguiente. o En caso de que dicho seguidor exista, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº3. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 69 3.3.2.2.4.4 Seguidor nº4 El seguidor nº 4 corresponde al que se halla justamente detrás del seguidor “fijo”, por lo que su procedimiento trabajará de la siguiente manera: o Si el seguidor “fijo” está en la última fila, b es igual a jj, no se realizará ningún cálculo y se pasará al siguiente caso puesto que eso significa que no habrá ningún seguidor en la posición del seguidor nº4. o En caso de que b sea menor que jj, se comprobará que en la posición (a, b+1) de la matriz de seguidores exista algún seguidor. En caso de que no sea así, todos los cálculos serán cero y se procederá a realizar el siguiente caso o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor 4. sx = XSEGFijo -PoscSegX(a , b + 1) sy = YSEGFijo -PoscSegY(a , b + 1) o Finalmente, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº4. Ha de tenerse en cuenta que en el caso de este seguidor, podrá dar sombra tanto en el caso de que sea antes como después del mediodía; es decir, para ambos signos del Azimut solar. El resto de cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 70 3.3.2.2.4.5 Seguidor nº5 Al igual que ocurría con los seguidores nº1 y nº3, el seguidor nº5 comparte procedimiento con el seguidor nº7. Como puede observarse la posición de estos dos también es oblicua al seguidor “fijo” pero en este caso, la separación respecto a este último es negativa en el eje x o eje Este- Oeste. La razón por la que estos cuatro seguidores se han agrupado de esta manera (1-3 y 5-7) se debe al valor del Azimut. Han sido agrupados en base al signo de éste puesto que dada su localización, los seguidores nº5 y nº7 proyectarán sombra sobre el seguidor “fijo” antes del mediodía solar. En este caso, por lo ya explicado, el Azimut será positivo. En el caso de estos dos seguidores, si el seguidor “fijo está en la última columna; es decir, la coordenada a es igual a ii, no se realizará ningún cálculo y se pasará al siguiente caso puesto que el seguidor a su izquierda no tendrá seguidores que le puedan hacer sombra. En el caso del seguidor nº5 el desarrollo del programa será el siguiente: o Si el seguidor “fijo” está en la última fila, b es igual a jj, no se realizará ningún cálculo y se pasará al siguiente caso puesto que no habrá ningún seguidor en la posición del seguidor nº5. o Si el Azimut es menor que 90º, el seguidor nº5 no proyectará sombra sobre el seguidor “fijo”, por lo que tampoco se realizará ningún cálculo y se pasará al siguiente caso. o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor nº5 cuyas coordenadas de la matriz de seguidores será: (a+1, b+1). sx = XSEGFijo -PoscSegX(a + 1, b + 1) 71 sy = YSEGFijo -PoscSegY(a + 1, b + 1) o Nuevamente se debe comprobar que el seguidor de esa posición existe; en caso negativo, no se realiza ningún cálculo y se pasa al siguiente. o En caso de que dicho seguidor exista, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor “fijo”, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº5. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.4.6 Seguidor nº6 El procedimiento a seguir en el caso del seguidor nº6 es muy similar al seguido con el seguidor nº2 teniendo en cuenta que están situados en posiciones opuestas. El desarrollo será el siguiente. o Si el seguidor “fijo” está en la última columna; es decir, a es igual a ii, no se realizará ningún cálculo y se pasará al siguiente puesto que no existirá ningún seguidor en la posición del seguidor nº6. o En el caso de que a no sea igual a jj, se comprobará que existe un seguidor en la posición correspondiente al seguidor nº6 en la matriz, cuyas coordenadas serán: (a+1, b). Si no existe, no se hace ningún calculo y se pasa al siguiente caso. o En el caso de que haya un seguidor en esa posición, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor nº6 72 sx = XSEGFijo -PoscSegX(a +1, b ) sy = YSEGFijo -PoscSegY(a + 1, b ) o Finalmente, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº6. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.4.7 Seguidor nº7 Como ya se ha comentado, el seguidor nº7 es tratado junto con el nº5 debido a las similitudes que comparten. Sin embargo, dentro de la aplicación común a ambos, existen tareas específicas del seguidor nº7 las cuales van a explicarse con mayor detenimiento a continuación: o Si el seguidor “fijo” está en la primera fila, b es igual a 1, no se realizará ningún cálculo y se pasará directamente al siguiente caso ya que no habrá posibilidad de que haya ningún seguidor en la posición del seguidor nº7. o Si el Azimut es mayor que 90º, el seguidor nº7 no proyectará sombra sobre el seguidor “fijo”, por lo que tampoco se realizará ningún cálculo y se pasará al siguiente caso. o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor nº7, cuyas coordenadas de la matriz de seguidores será: (a-1, b+1). 73 sx = XSEGFijo -PoscSegX(a + 1, b - 1) sy = YSEGFijo -PoscSegY(a + 1, b -1) o Nuevamente se debe comprobar que el seguidor de esa posición existe; en caso negativo, no se realiza ningún cálculo y se pasa al siguiente. o En caso de que dicho seguidor exista, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº7. Estos cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.4.8 Seguidor nº8 Al igual que ocurría en el caso del seguidor nº2 y nº6, el procedimiento del seguidor nº8 es muy semejante al del nº4; siendo sus posiciones opuestas. En el caso del seguidor nº8 su posición corresponde al que está justamente delante del seguidor “fijo”. El desarrollo de su procedimiento será el siguiente: o Si el seguidor “fijo” está en la primera fila; es decir, b es igual a 1, no se realizará ningún cálculo y se pasará al siguiente caso puesto que eso supone que no hay ningún seguidor en la posición del seguidor nº8. o En caso de que b sea mayor que 1, se comprobará que en la posición (a, b-1) de la matriz de seguidores exista algún seguidor. En caso de que no sea así, todos los cálculos serán cero y se procederá a realizar el siguiente caso 74 o Si se han superada estas condiciones, se procederá a calcular la distancia que separa, en ejes x e y globales, el seguidor “fijo” de aquel que se encuentre en la posición del seguidor nº8. sx = XSEGFijo -PoscSegX(a , b - 1) sy = YSEGFijo -PoscSegY(a , b - 1) o Finalmente, se procederá a realizar los cálculos de la sombra; el plano que corresponde al seguidor será el del seguidor fijo, mientras que los planos formados con las proyecciones de las sombras serán los del seguidor que corresponda a la posición del seguidor nº8. Ha de tenerse en cuenta que en el caso de este seguidor, podrá dar sombra tanto en el caso de que sea antes como después del mediodía; es decir, para ambos signos del Azimut solar. El resto de cálculos se realizarán según lo expuesto en el apartado de cálculos previos. 3.3.2.2.5 Final del programa Una vez visto el funcionamiento del programa para cada uno de los seguidores, falta comentar el final del programa. Esta última parte lo que hace es tratar los datos obtenidos de forma que cumplan la función que se desea. Para ello realiza diferentes pasos: o Para cada caso, habrá cuatro variables finales: AreaPerdidas, Area, AreaPerdidasTotal, AreaTotal Las dos primeras renovarán su valor en cada nuevo caso, mientras que las dos últimas aumentarán su 75 valor la cantidad correspondiente a las dos anteriores en cada nuevo caso; es decir, AreaPerdidas = basex * basey Area = BaseP * AlturaP AreaPerdidasTotal = AreaPerdidasTotal + AreaPerdidas AreaTotal = AreaTotal + Area La primera y la tercera; AreaPerdidas y AreaPerdidasTotal se refieren al área de la sombra, mientras que las otras dos registran el área total del seguidor. De esta manera lo que hace es ver el área que hay en sombra y el área que captaría radiación en caso de no haber sombra. o Como la salida de datos se realiza mes a mes, cuando va a cambiar de mes hace el cálculo del porcentaje de sombra respecto del área total: PorcPerdidas = (AreaPerdidasTotal / AreaTotal) Además inicializa las variables AreaPerdidasTotal y AreaTotal a cero de forma que estén preparadas para comenzar el cálculo de un nuevo mes. o Por otra parte, cada vez que cambia de seguidor “fijo”, lo que supone que ya ha realizado el cálculo de sombras del seguidor anterior durante el año completo, inicializada la variable Dia a cero con el fin de que los cálculos del nuevo seguidor sean correctos. 3.3.2.3 Presentación de los resultados en tabla de Excel. La presentación de los resultados se realiza en una tabla de Excel donde cada fila corresponde a un seguidor y cada columna a un mes del año. Al principio del programa, abre un documento de Excel y asigna, en la fila número 1 a patir de la columna número 2 (B), a cada mes una columna de tal forma que: 76 o Enero: Fila 1, Columna B o Febrero: Fila1, Columna C o Así sucesivamente hasta: Diciembre: Fila1 Columna M En el código puede apreciarse como se realiza dicha asignación. Además realiza algunas acciones como cambiar el tamaño de la letra y resaltarla mediante la función “Negrita”. ApExcel.cells(1, 2).formula = "Enero" ApExcel.cells(1, 3).formula = "Febrero" ApExcel.cells(1, 4).formula = "Marzo" ApExcel.cells(1, 5).formula = "Abril" ApExcel.cells(1, 6).formula = "Mayo" ApExcel.cells(1, 7).formula = "Junio" ApExcel.cells(1, 8).formula = "Julio" ApExcel.cells(1, 9).formula = "Agosto" ApExcel.cells(1, 10).formula = "Septiembre" ApExcel.cells(1, 11).formula = "Octubre" ApExcel.cells(1, 12).formula = "Noviembre" ApExcel.cells(1, 13).formula = "Diciembre" ApExcel.range("b1:m1").Font.Size = 10 ApExcel.range("b1:m1").Font.Bold = True El resto de la tabla se rellena al final del programa, antes de cambiar de un mes a otro. Lo primero que ha de hacer es indicar, en la primera columna, el seguidor con el que está trabajando. ApExcel.cells(SeguidorNumero + 1, 1).formula = "Seguidor" & SeguidorNumero ApExcel.cells(SeguidorNumero + 1, 1).Font.Size = 10 ApExcel.cells(SeguidorNumero + 1, 1).Font.Bold = True A continuación escribe, en el lugar que le corresponda, el porcentaje de sombra calculado. Este dato se introduce con estilo de porcentaje y formato de número “0.00%”. 77 ApExcel.cells(SeguidorNumero + 1, Mes + 1).formula = PorcPerdidas ApExcel.cells(SeguidorNumero + 1, Mes + 1).Style = "Percent" ApExcel.cells(SeguidorNumero + 1, Mes + 1).NumberFormat = "0.00%" 3.4 Implantación numérica La implantación numérica va a realizarse para varios casos diferentes, cuatro concretamente. Los cuatro casos van a tener unas diferencias significativas entre sí de cara a comprobar el buen funcionamiento del programa en el análisis de los resultados. En cada uno de los cuatro casos será una única variable la que cambie respecto al anterior para poder comprobar como afecta dicho cambio. Lo que se pretende es comprobar que, por ejemplo, al cambiar las dimensiones del seguidor, cambia el porcentaje de sombra. Los cuatro casos que se van a implantar son los siguientes: o Un plano que contiene 100 seguidores, cuya separación es de 20 metros en el eje Norte-Sur y de 25 metros en el eje EsteOeste. El seguidor será de 18 * 10 metros, altura de la columna=5m. La comunidad Autónoma es Granada. o Las mismas condiciones anteriores pero en Guipúzcoa. o En este caso se tiene el mismo plano, Comunidad Autónoma Guipúzcoa. Seguidor: 14*10 metros, altura de la columna=5m. o Por último, se repite el caso anterior esta vez con un nuevo plano que contiene 9 seguidores y cuya separación es de 10 metros Norte-Sur, 10 metros Este-Oeste. Las tablas obtenidas en los casos de los 100 seguidores son excesivamente largas por lo que se ha optado por reproducir únicamente partes de ellas; partes que puedan ser relevantes a la hora de valorar los resultados. Caso1 78 79 Caso 2 80 Caso 3 81 Caso4 82 4 Análisis de los resultados 83 4 Análisis de los resultados Parta facilitar el análisis de los resultados, a continuación se numera los seguidores en función de la tabla de resultados donde el seguidor q es el que más al Sur y más al Oeste de todos; es decir, corresponde con el de la esquina inferior izquierda del plano. Imagen Imagen Una vez realizada la implantación numérica y obtenidos los resultados expuestos en el capítulo anterior, se procede a su análisis. Dada la extensión de las tres primeras tablas de resultados, se ha omitido parte de las mismas. Como puede comprobarse, de la tabla del caso 1 es de la que 84 más partes se han expuesto; esto se debe a que a través de ésta se va a ver que los diferentes valores que adopta el valor de la sombra se debe al diseño del plano. 4.1 Caso 1 Con este caso lo que se pretende es ver si los diferentes valores de sombra tienen relación con las diferentes posiciones de los seguidores. Para empezar se observa que los valores más pequeños corresponden con los seguidores que se encuentran en las esquinas y, concretamente, los de las dos esquinas de la primera fila registran los valores más pequeños. (Seguidor1 y seguidor 92). Esto se debe a que las posiciones en las que estos dos no tienen seguidores son las posiciones orientadas hacia el Sur que son las que mayores sombras proyectan. Por otro lado se puede observar como los seguidores de la primera columna(1 al 16) registran valores inferiores a los de la segunda (17 al 32). Concretamente, los seguidores del 18 al 31 serían seguidores que mantienen la configuración del seguidor genérico que se ha definido por lo que serían éstos los que mayores valores de sombra deberían registrar y así es. En las tablas que van del seguidor 43 al 48 y del seguidor 59 al 64 podemos observar la diferencia entre unos seguidores con la configuración del genérico y otros que a su derecha no tienen seguidores que les den sombra. Comprobar que estos valores sí se diferencian permite cerciorarse de que la obtención de datos desde AutoCAD y la forma de ordenarlos es correcta puesto que es capaz de una vez diseñada la matriz completa, comprobar en qué lugares de dicha matriz no existen seguidores. 4.2 Caso 1-2 En este apartado de lo que se trata es de comparar el caso 1 con el 2. Lo único que diferencia estos dos casos es el lugar en el que están ubicados: Granada y Guipúzcoa. Lo que se pretende con esto es comprobar que un cambio en la variable latitud comporta un cambio en los resultados para comprobar que el cálculo de las variables que definen la posición del sol se están realizando correctamente. 85 La razón por la que se han elegido estas dos localidades es simplemente sus valores de latitud, que se encuentran entre las mayores y las menores dentro de España. El valor de la latitud en Granada es de 37.2º y en Guipúzcoa de 43.3º Mirando las tablas de resultados podemos comprobar que efectivamente existe una variación de unos resultados a otros. En general, el caso de Guipúzcoa, la sombra que recibe cada uno de los seguidores es mayor que en el caso de Granada. Esto se debe a que la trayectoria del sol en el caso de una latitud de 43º es más bajo que en el caso de la latitud de 37º y por lo tanto, las sombras serán más alargadas en el primer caso. Las siguientes imágenes muestran la trayectoria del sol sobre un punto de la tierra a lo largo del año para ambos casos. La primera es la trayectoria para una latitud de 43º mientras que la segunda muestra el mismo caso para una latitud de 37º. Observando ambas imágenes puede apreciarse como en el primer caso las marcas que limitan la trayectoria del sol tiene mayor inclinación que en el segundo caso. Además ambas imágenes representan el mismo momento en el tiempo, el día 2 de Marzo a las 8 de la mañana. En este instante tanto el azimut como la altura solares son menores en el primer caso. Sin embargo, aunque en general los valores de las sombras son mayores para el caso de Guipúzcoa, los seguidores que ocupan la primera fila, en los meses de invierno, reciben menos sombra que en el caso de Granada. Este hecho no deja de ser razonable, puesto que los seguidores de la primera fila carecen de seguidores en las posiciones en las que se proyecta mayor sombra en invierno, especialmente en la posición sur. 86 4.3 Caso 2-3 El caso 2 y el caso 3 se diferencian entre sí en las dimensiones del seguidor; concretamente en la dimensión de la base del módulo de parrillas que en el caso 2 vale 18 y en el 3, 14. Las proyecciones de la sombra en el primer caso deberían ser mayores que en el segundo, puesto que las distancias que separan a unos seguidores de otros son las mismas en ambos casos. A la vista de los resultados, se confirma este hecho. 87 4.4 Caso 3-4 Por último, la diferencia entre el caso 3 y el caso 4 es la distancia existente entre los seguidores. Dichas distancias en cada uno de los casos son las que aparecen a continuación. Caso3 Caso4 Como se ve, la variación de las distancias es bastante considerable por lo que debería existir una diferencia significativa entre unos valores de sombras y otros. Los resultados confirman este hecho, dado que en los seguidores centrales, en el mes de Enero, cuando se registran mayores sombras, pasa de un valor del 1.51% al 13.08% y en el caso del seguidor 1, para ese mismo mes los resultados son de 0.05% y 1.91% respectivamente. 88 5 Conclusiones 89 5 Conclusiones 5.1 Conclusiones sobre los resultados Observando los resultados obtenidos, se puede concluir que el programa desarrollado cumple las funciones para las que se ha diseñado. Proporciona unos datos útiles y claros de las sombras proyectadas sobre cada seguidor fotovoltaico dentro de una huerta solar. Además estos datos se proporcionan individualmente para cada seguidor y mes a mes lo que permite estudiar detalladamente cada configuración y permite comparar fáciles distintas configuraciones. Además permite, sin necesidad de involucrarse en exceso en el estudio del movimiento del sol y la proyección de sombras, tras probar algunos diseños diferentes, poder obtener una idea aproximada de la forma en que éstos influyen sobre la instalación. El uso de la aplicación es sumamente sencillo. El único detalle a tener en cuenta es la necesidad de introducir el plano en formato DXF, lo cual tampoco entraña ninguna dificultad. 5.2 Recomendaciones para futuros estudios A lo largo del desarrollo del presente proyecto se han ido encontrando múltiples problemas así como variantes del mismo. Muchos de dichos problemas se han ido solucionando mientras que otros han limitado la generalidad del proyecto debido a la complejidad que suponían. El principal problema era la falta de documentación que pudiera servir de base para desarrollar el proyecto; por lo tanto, éste puede cumplir esa función. Algunas posibles ampliaciones de este proyecto bastante recomendables serían aquellas que permitieran dibujar las sombras calculadas, permitir que cada seguidor sea de dimensiones diferentes, ampliar las posibles ubicaciones. Por otro lado también podría diseñarse una aplicaciones que hiciese lo contrarío a ésta; es decir, a partir de un terreno dado y un rendimiento deseado (lo que implica una cantidad de sombra máxima), estimar la disposición de los 90 seguidores. De esta forma se podría cerrar el ciclo. Para desarrollar esta aplicación también sirve como base el presente proyecto puesto que realiza todos los cálculos correspondientes a las sombras. 91 6 Bibliografía 92 6 Bibliografía • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • [UNED 05] Programa de postgrado (UNED). V Curso De Experto Profesional en Energía Fotovoltaica. Visual Basic 6 a fondo. Inforbooks ediciones. Sergio Arboles y Luis Navarro. VBA for AutoCAD2002. Writing AutoCAD macros. Jeffrey E. Clark Aprenda Visual Basic como si estuviera en primero. Javier García de Jalón , José Ignacio Rodríguez , Alfonso Brazález Retratos de la conexión fotovoltaica a la red (IV). Seguidores y huertas solares.Eduardo Lorenzo. Instituto de energía solar. Universidad politécnica de Madrid. Manual del usuario. AutoCAD 2006. www.canalvisualbasic.net www.recursosvisualbasic.com. www.vb-mundo.com www.elguille.info msdn.microsoft.com/vbasic www.portalvb.comv vbasic.astalaweb.com www.lawebdelprogramador.com/ www.vbsiglo21.net [GUÍA 03] Guía Solar de Greenpeace [ASIF] Página web de la Asociación de la Industria Fotovoltaica (ASIF). www.asif.org [IDAE 04]Guía práctica de la energía. Consumo eficiente y responsable. IDAE, 2004 www.isofoton.es www.bpsolar.com www.ibersolar.com [RD 436/2004] R.D. 436/2004 de 12 de marzo [FENO] www.unionfenosa.es [PLAN 06] Conferencia: Posicionamiento político en la planificación energética nacional. La cuestión nuclear. [AYTO 06] www.ayto-coslada.es www.censolar.es [WIKI 06] http://es.wikipedia.org/ [EKO] http://www.ekogaia.net http://tecnologias.gio.etsit.upm.es/domotica www.ine.es http://www.terra.org/html/s/ecologia.html [IBER 05] http://bdd.unizar.es/pag3/pag6-1/potencia.htm 93 7 Apéndice 94 7 . Apéndice El presente apéndice se adjunta para facilitar la comprensión del código. Lo que se pretende es explicar algunos comandos propios de la programación cuya utilización se repite muy a menudo a lo largo del código 7.1 Estructuras de decisión Son las encargadas de comprobar condiciones, y dependiendo de los resultados, realizar diferentes operaciones. 7.1.1 Sentencia IF ... THEN ... ELSE ... Esta estructura permite ejecutar condicionalmente una o más sentencias y puede escribirse de dos formas. La primera ocupa sólo una línea y tiene la forma siguiente: If condicion Then sentencia1 [Else sentencia2] La segunda es más general y se muestra a continuación: If condicion Then sentencia(s) [Else sentencia(s)] End If Si condicion es True (verdadera), se ejecutan las sentencias que están a continuación de Then, y si condicion es False (falsa), se ejecutan las sentencias que 95 están a continuación de Else, si esta cláusula ha sido especificada (pues es opcional). Para indicar que se quiere ejecutar uno de varios bloques de sentencias dependientes cada uno de ellos de una condición, la estructura adecuada es la siguiente: If condicion1 Then sentencias1 ElseIf condicion2 Then sentencias2 Else sentencia-n End If Si se cumple la condicion1 se ejecutan las sentencias1, y si no se cumple, se examinan secuencialmente las condiciones siguientes hasta Else, ejecutándose las sentencias correspondientes al primer ElseIf cuya condición se cumpla. Si todas las condiciones son falsas, se ejecutan las sentencias-n correspondientes a Else, que es la opción por defecto. La Figura 7.1 presenta esquemáticamente ambas formas de representar estas sentencias: 7.1.2 Sentencia SELECT CASE Esta sentencia permite ejecutar una de entre varias acciones en función del valor de una expresión. Es una alternativa a If ... Then ... ElseIf cuando se 96 compara la misma expresión con diferentes valores. Su forma general es la siguiente: Select Case expresion Case etiq1 [sentencias1] Case etiq2 [sentencias2] Case Else sentenciasn End Select Donde expresión es una expresión numérica o alfanumérica, y etiq1, etiq2, ... pueden adoptar distintas formas, en el presente proyecto se han utilizado las siguientes: 1. expresión 2. combinación de expresiones separadas por comas Cuando se ejecuta una sentencia Select Case, Visual Basic evalúa la expresión y el control del programa se transfiere a la sentencia cuya etiqueta tenga el mismo valor que la expresión evaluada, ejecutando a continuación el correspondiente bloque de sentencias. Si no existe un valor igual a la expresión entonces se ejecutan las sentencias a continuación de Case Else. 7.2 Estructuras de bucle También son llamadas repetitivas. Se utilizan para ejecutar una o más líneas de código un número determinado de veces. 7.2.1 Sentencia FOR ... NEXT La sentencia For da lugar a un lazo o bucle, y permite ejecutar un conjunto de sentencias cierto número de veces. Su forma general es: For variable = expresion1 To expresion2 [Step expresion3] 97 [sentencias] Exit For [sentencias] Next [variable] Cuando se ejecuta una sentencia For, primero se asigna el valor de la expresion1 a la variable y se comprueba si su valor es mayor o menor que la expresion2. En caso de ser menor se ejecutan las sentencias, y en caso de ser mayor el control del programa salta a las líneas a continuación de Next. Todo esto sucede en caso de ser la expresion3 positiva. En caso contrario se ejecutarán las sentencias cuando la variable sea mayor que expresion2. Una vez ejecutadas las sentencias, la variable se incrementa en el valor de la expresion3, o en 1 si Step no se especifica, volviéndose a efectuar la comparación entre la variable y la expresion2, y así sucesivamente. La sentencia Exit For es opcional y permite salir de un bucle For ... Next antes de que éste finalice. 7.2.2 Sentencia DO…LOOP Un Loop (bucle) repite la ejecución de un conjunto de sentencias mientras una condición dada sea cierta, o hasta que una condición dada sea cierta. La condición puede ser verificada antes o después de ejecutarse el conjunto de sentencias. Sus posibles formas son las siguientes: ’ Formato 1: Do [{While/Until} condicion] [sentencias] [Exit Do] [sentencias] Loop ’ Formato 2: Do 98 [sentencias] [Exit Do] [sentencias] Loop [{While/Until}condicion] La sentencia opcional Exit Do permite salir de una bucle Do ... Loop antes de que finalice éste. La representación esquemática del mismo sería la siguiente: En el código desarrollado en este proyecto se ha utilizado el formato 2 con while. Con este formato el bucle se ejecuta al menos una vez y se continuará ejecutando mientras se cumpla la condición. 99 8 Código 100 'Agosto 'Prueba Option Explicit Const PI As Double = 3.14159265359 Dim Dibujoname As String 'VARIABLES PARA CÁLCULO DE ÁNGULOS Dim w As Single: Dim wGrad As Integer Dim DecliRad(1 To 365) As Double: Dim AlturaRad(1 To 365, 1 To 24) As Double: Dim AzimutRad(1 To 365, 1 To 24) As Double Dim L As Single: Dim AnguloNormalRad(1 To 365, 1 To 24) As Double: Dim Incli As Single: Dim Desviacion As Single Dim XD As Double: Dim X1 As Double: Dim X2 As Double: Dim X3 As Double 'Dim Hora As Integer Dim DecliGrad(1 To 365) As Double: Dim AlturaGrad(1 To 365, 1 To 24) As Double: Dim AzimutGrad(1 To 365, 1 To 24) As Double Dim AnguloNormalGrad(1 To 365, 1 To 24) As Double Dim AnguloNormalSeg As Single Dim Altura As Single: Dim Azimut As Single 'DATOS DEL SEGUIDOR Dim BaseP As Single: Dim AlturaP As Single: Dim h As Integer: Dim AlturaColumna As Integer 'VARIABLES PARA EL CÁLCULO DE LA SOMBRA Dim h1(1 To 365, 1 To 24) As Single: Dim h2(1 To 365, 1 To 24) As Single Dim d1(1 To 365, 1 To 24) As Single: Dim d2(1 To 365, 1 To 24) As Single Dim AlturaSeg As Single: Dim AngMax As Single: Dim AnguloNormal As Single 'Variables para calculo de coordenadas Dim XL As Single: Dim YL As Single: Dim ZL As Single Dim G As Single 'CÁLCULO DE LOS ÁNGULOS Function CalculoAngulos1(N As Integer, Hora As Single) XD = (0.973 * N - 77.84) * PI / 180 DecliRad(N) = (23.45 * PI / 180) * Sin(XD) wGrad = Abs(12 - Hora) * 15 w = wGrad * PI / 180 Desviacion = 0 X1 = Cos(L) * Cos(DecliRad(N)) * Cos(w) + Sin(L) * Sin(DecliRad(N)) If X1 < 0 Then CalculoAngulos1 = 0 Exit Function Else If -X1 * X1 + 1 = 0 Then AlturaRad(N, Hora) = PI / 2 101 Else AlturaRad(N, Hora) = Atn(X1 / Sqr(-X1 * X1 + 1)) End If End If 'Arcoseno CalculoAngulos1 = AlturaRad(N, Hora) End Function Function CalculoAngulos2(N As Integer, Hora As Single) Altura = CalculoAngulos1(N, Hora) If Altura = 0 Then CalculoAngulos2 = 0 Exit Function Else X2 = Cos(DecliRad(N)) * Sin(w) / Cos(Altura) X3 = (Sin(L) * Sin(Altura) - Sin(DecliRad(N))) / (Cos(L) * Cos(Altura)) If X2 >= 0 Then If X3 > 0 Then '1er cuadrante If X2 = 1 Then AzimutRad(N, Hora) = PI / 2 Else AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) 'Arcoseno End If Else '2º cuadrante AzimutRad(N, Hora) = Atn(-X3 / Sqr(-X3 * X3 + 1)) + 2 * Atn(1) 'Arcocoseno End If ElseIf X3 > 0 Then '4º Cuadrante AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) 'Arcoseno Else '3º cuadrante If X2 = -1 Then AzimutRad(N, Hora) = -PI / 2 Else AzimutRad(N, Hora) = Atn(X2 / Sqr(-X2 * X2 + 1)) - (PI / 2) 'Arcoseno End If End If End If If Hora <= 12 Then CalculoAngulos2 = AzimutRad(N, Hora) Else CalculoAngulos2 = -AzimutRad(N, Hora) End If AnguloNormalRad(N, Hora) = (PI / 2) - AlturaRad(N, Hora) AlturaGrad(N, Hora) = AlturaRad(N, Hora) * 180 / PI AzimutGrad(N, Hora) = AzimutRad(N, Hora) * 180 / PI 102 AnguloNormalGrad(N, Hora) = AnguloNormalRad(N, Hora) * 180 / PI DecliGrad(N) = DecliRad(N) * 180 / PI End Function 'CÁLCULO DE d, DISTANCIA DE LA SOMBRA Function DistanciaSombra1(N As Integer, Hora As Single, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If If Altura = 0 Then d1(N, Hora) = 0 Else h1(N, Hora) = h - (AlturaP * Sin((PI / 2) - AlturaSeg) / 2) d1(N, Hora) = h1(N, Hora) / Tan(Altura) End If DistanciaSombra1 = d1(N, Hora) End Function Function DistanciaSombra2(N As Integer, Hora As Single, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If If Altura = 0 Then d2(N, Hora) = 0 Else h2(N, Hora) = h + (AlturaP * Sin((PI / 2) - AlturaSeg) / 2) d2(N, Hora) = h2(N, Hora) / Tan(Altura) End If DistanciaSombra2 = d2(N, Hora) End Function Function LocalesAGlobales(N As Integer, Hora As Single, Coord As Integer, Punto As Integer, Sombra As Integer, h As Single, AngMax As Single) Azimut = CalculoAngulos2(N, Hora) If Coord = 1 Then XL = XLSeguidor(Punto) YL = YLSeguidor(N, Hora, Punto, Sombra, h, AngMax) G = XL * Cos(Azimut) - YL * Sin(Azimut) ElseIf Coord = 2 Then XL = XLSeguidor(Punto) YL = YLSeguidor(N, Hora, Punto, Sombra, h, AngMax) G = XL * Sin(Azimut) + YL * Cos(Azimut) Else G = ZLSeguidor(N, Hora, Punto, h) 103 End If LocalesAGlobales = G End Function Function XLSeguidor(Punto As Integer) Select Case Punto Case 1, 2 XL = BaseP / 2 Case 3, 4 XL = -BaseP / 2 End Select XLSeguidor = XL End Function Function YLSeguidor(N As Integer, Hora As Single, Punto As Integer, Sombra As Integer, h As Single, AngMax As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If AnguloNormalSeg = (PI / 2) - AlturaSeg If Sombra = 0 Then Select Case Punto Case 1, 4 YL = AlturaP * Cos(AnguloNormalSeg) / 2 Case 2, 3 YL = -(AlturaP * Cos(AnguloNormalSeg) / 2) End Select ElseIf Sombra = 1 Then Select Case Punto Case 1, 4 YL = (AlturaP / 2) - DistanciaSombra1(N, Hora, h, AngMax) * Cos(AnguloNormalSeg) Case 2, 3 YL = -((AlturaP / 2) + DistanciaSombra2(N, Hora, h, AngMax)) * Cos(AnguloNormalSeg) End Select End If YLSeguidor = YL End Function Function ZLSeguidor(N As Integer, Hora As Single, Punto As Integer, h As Single) Altura = CalculoAngulos1(N, Hora) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura 104 End If Select Case Punto Case 1, 4 ZL = h - (AlturaP * Cos(AlturaSeg) / 2) Case 2, 3 ZL = h + (AlturaP * Cos(AlturaSeg) / 2) End Select ZLSeguidor = ZL End Function Function DistanciaMinNS(Sombra As Integer, h As Single, AngMax As Single) Dim Dia As Integer: Dim HoraDia As Single Dia = 355 HoraDia = 8 Dim ko As Single Dim ZG3 As Single: Dim ZG4 As Single: Dim DistNS As Single: Dim LNS As Single ko = 4 * PI / 180 Altura = CalculoAngulos1(Dia, HoraDia) Azimut = CalculoAngulos2(Dia, HoraDia) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If ZG3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, h, AngMax) ZG4 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, h, AngMax) LNS = ZG3 - ZG4 DistNS = ((LNS / Tan(Altura)) + AlturaP * Cos(AlturaSeg)) * Cos(Azimut) DistanciaMinNS = DistNS End Function Function DistanciaMinEO(Sombra As Integer, h As Single, AngMax As Single) Dim Dia As Integer: Dim HoraDia As Single Dia = 355 HoraDia = 8 Dim ko As Single Dim ZG1 As Single: Dim ZG2 As Single: Dim DistEO As Single: Dim LEO As Single ko = 4 * PI / 180 Altura = CalculoAngulos1(Dia, HoraDia) Azimut = CalculoAngulos2(Dia, HoraDia) If Altura < AngMax Then AlturaSeg = AngMax Else AlturaSeg = Altura End If ZG2 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, h, AngMax) ZG1 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, h, AngMax) LEO = ZG2 - ZG1 DistEO = ((LEO / Tan(Altura)) + BaseP * Cos(AlturaSeg)) * Sin(Azimut) DistanciaMinEO = DistEO 105 End Function Private Sub cmdBuscar_Click() CommonDialog1.Filter = "(*.dxf)|*.dxf" 'Abrimos el Commondialog con ShowOpen CommonDialog1.ShowOpen 'Si seleccionamos un archivo mostramos la ruta If CommonDialog1.FileName <> "" Then TxtPath.Text = CommonDialog1.FileName Dibujoname = CommonDialog1.FileName Else 'Si no mostramos un texto de advertencia de que no se seleccionó _ ninguno, ya que FileName devuelve una cadena vacía TxtPath.Text = "No se seleccionó ningún archivo" End If End Sub Private Sub cmdCalcular_Click() Dim Dibujoobj Dim Dibujo Dim xDibujo() As String: Dim yDibujo() As String: Dim zDibujo() As String Dim Etiqueta As String: Dim linea As String Dim comparador As String: Dim i As Long Dim XX As Boolean: Dim YY As Boolean: Dim ZZ As Boolean Dim Filas As Long: Dim cont As Long: Dim j As Long 'f06name = Application.GetOpenFilename("Autocad output(*.dxf),*.dxf",) Set Dibujoobj = CreateObject("Scripting.FileSystemObject") Set Dibujo = Dibujoobj.OpenTextFile(Dibujoname, 1) 'Dibujo.skipline 'Text1.Text = Dibujo.readline Do While StrComp(Dibujo.readline, "EOF") <> 0 Filas = Filas + 1 Loop Dibujo.Close Dim NumerodeSeguidores As Integer Dim fin As Integer Dim Numseguidores As Integer 106 Dim Dia As Integer Dim HoraDia As Single NumerodeSeguidores = txtNSeguidores.Text Numseguidores = NumerodeSeguidores Dim ApExcel1 As Variant Set ApExcel1 = CreateObject("Excel.application") ApExcel1.workbooks.open ("C:\Documents and Settings\Paula Calles\My Documents\Proyecto\Tablas para el proyecto.xls") 'VARIABLES PARA INTERCAMBIO DINAMICO DE DATOS(COMUNIDAD==LATITUD) Dim Columna As String Dim ColumnaA As String Dim Fila As Integer 'COMUNIDAD==LATITUD For Fila = 72 To 123 Latitud.LinkMode = 0 Latitud.LinkTopic = "Excel|Hoja1" Latitud.LinkItem = "F" & Fila & "C1" Latitud.LinkMode = 1 ColumnaA = "F" & CStr(Fila) & "C1" Latitud.LinkItem = ColumnaA If Left(Latitud.Text, Len(cmbComunidad)) = cmbComunidad Then Latitud.LinkMode = 0 Latitud.LinkTopic = "Excel|Hoja1" Latitud.LinkItem = "F" & Fila & "C3" Latitud.LinkMode = 1 ColumnaA = "F" & CStr(Fila) & "C3" Latitud.LinkItem = ColumnaA Exit For End If Next L = (Latitud.Text) * PI / 180 ApExcel1.workbooks("Tablas para el proyecto.xls").Close savechanges:=False Do Set Dibujoobj = CreateObject("Scripting.FileSystemObject") Set Dibujo = Dibujoobj.OpenTextFile(Dibujoname, 1) For cont = 1 To Filas Do linea = Dibujo.readline j=j+1 If j > Filas Then 107 Exit For End If Loop While StrComp(linea, "SEGUIDORES") <> 0 Do linea = Dibujo.readline j=j+1 Loop While StrComp(linea, " 10") <> 0 i=i+1 ReDim Preserve xDibujo(i) ReDim Preserve yDibujo(i) ReDim Preserve zDibujo(i) xDibujo(i) = Dibujo.readline Dibujo.skipline yDibujo(i) = Dibujo.readline Dibujo.skipline zDibujo(i) = Dibujo.readline j=j+5 Next Dibujo.Close 'Text1.Text = i Dim posicion As Integer Dim ii As Integer Dim xSeg() As Single: Dim ySeg() As Single: Dim zSeg() As Single Dim XSEGUIDOR() As Single: Dim YSEGUIDOR() As Single Dim compara As Double ii = 0 ReDim xSeg(1 To Numseguidores) ReDim ySeg(1 To Numseguidores) ReDim zSeg(1 To Numseguidores) ReDim XSEGUIDOR(1 To Numseguidores) ReDim YSEGUIDOR(1 To Numseguidores) For posicion = (i - (Numseguidores - 1)) To i ii = ii + 1 zSeg(ii) = Val(zDibujo(posicion)) xSeg(ii) = Val(xDibujo(posicion)) ySeg(ii) = Val(yDibujo(posicion)) Next 108 XSEGUIDOR() = xSeg() YSEGUIDOR() = ySeg() 'Text1.Text = ySeg(NumSeguidores) Dim ORDENX() As Single: Dim POSICIONX() As Integer ReDim ORDENX(1 To Numseguidores) ReDim POSICIONX(1 To Numseguidores) compara = 0.1 j=0 For j = 1 To Numseguidores compara = 0.1 For i = 1 To Numseguidores If xSeg(i) > compara Then compara = xSeg(i) posicion = i End If Next ORDENX(j) = compara POSICIONX(j) = posicion xSeg(posicion) = 0 Next 'Text1.Text = ORDENX(83) Dim ORDENY() As Single: Dim POSICIONY() As Integer ReDim ORDENY(1 To Numseguidores) ReDim POSICIONY(1 To Numseguidores) compara = 0.1 j=0 For j = 1 To Numseguidores 109 compara = 0.1 For i = 1 To Numseguidores If ySeg(i) > compara Then compara = ySeg(i) posicion = i End If Next ORDENY(j) = compara POSICIONY(j) = posicion ySeg(posicion) = 0 Next xSeg() = ORDENX() ii = 0 For j = 1 To Numseguidores If xSeg(j) <> 0 Then compara = xSeg(j) ii = ii + 1 For i = 1 To Numseguidores If xSeg(i) = compara Then xSeg(i) = 0 End If Next End If Next 'Text1.Text = ii Dim jj As Integer 110 ySeg() = ORDENY() jj = 0 For j = 1 To Numseguidores If ySeg(j) <> 0 Then compara = ySeg(j) jj = jj + 1 For i = 1 To Numseguidores If ySeg(i) = compara Then ySeg(i) = 0 End If Next End If Next 'Text1.Text = ORDENX(3) Dim PoscSegX1() As Single: Dim PoscSegY1() As Single: Dim PoscSegZ1() As Single Dim a As Integer: Dim b As Integer Dim posx() As Integer: Dim posy() As Integer ReDim posx(1 To Numseguidores) b=0 a=0 xSeg() = ORDENX() For i = 1 To Numseguidores If xSeg(i) <> 0 Then b=b+1 compara = xSeg(i) For j = 1 To Numseguidores If xSeg(j) = compara Then a = POSICIONX(j) posx(a) = b xSeg(j) = 0 End If 111 Next End If Next ReDim posy(1 To Numseguidores) b=0 a=0 ySeg() = ORDENY() For i = 1 To Numseguidores If ySeg(i) <> 0 Then b=b+1 compara = ySeg(i) For j = 1 To Numseguidores If ySeg(j) = compara Then a = POSICIONY(j) posy(a) = b ySeg(j) = 0 End If Next End If Next 'Text1.Text = posx(15) Dim c As Integer ReDim PoscSegX1(1 To ii, 1 To jj): ReDim PoscSegY1(1 To ii, 1 To jj): ReDim PoscSegZ1(1 To ii, 1 To jj) For i = 1 To Numseguidores For j = 1 To Numseguidores If POSICIONX(j) = i Then a = posx(i) b = posy(i) c = POSICIONX(j) 112 PoscSegX1(a, b) = XSEGUIDOR(c) PoscSegY1(a, b) = YSEGUIDOR(c) PoscSegZ1(a, b) = zSeg(c) End If Next Next ' Text1.Text = PoscSegX1(ii, jj) Dim PoscSegX() As Single: Dim PoscSegY() As Single: Dim PoscSegZ() As Single ReDim PoscSegX(ii, jj): ReDim PoscSegY(ii, jj): ReDim PoscSegZ(ii, jj) i=0 j=0 For a = ii To 1 Step -1 i=i+1 For b = jj To 1 Step -1 j=j+1 PoscSegX(i, j) = PoscSegX1(a, b) PoscSegY(i, j) = PoscSegY1(a, b) PoscSegZ(i, j) = PoscSegZ1(a, b) Next j=0 Next Dim Distancia1 As Single: Dim Distancia2 As Single Dim AlturaColumna As Single AlturaP = txtAltura.Text BaseP = txtBase.Text AlturaColumna = txtAltColumna.Text AngMax = (90 - txtAngMax.Text) * PI / 180 Dim XG1 As Single Dim DNS As Single: Dim DEO As Single 'VARIABLES PARA CÁLCULO DEL ÁREA DE LA SOMBRA 113 Dim r1 As Single: Dim r2 As Single: Dim r3 As Single Dim s1 As Single: Dim s2 As Single: Dim s3 As Single Dim t1 As Single: Dim t2 As Single: Dim t3 As Single Dim v1 As Single: Dim v2 As Single: Dim v3 As Single Dim w1 As Single: Dim w2 As Single: Dim w3 As Single Dim u1 As Single: Dim u2 As Single: Dim u3 As Single Dim d As Single: Dim e As Single: Dim f As Single Dim a1 As Double: Dim b1 As Single: Dim a3 As Single Dim a2 As Single: Dim b2 As Single: Dim b3 As Single Dim X: Dim Y As Single: Dim z As Single Dim basex As Single: Dim basey As Single: Dim Area As Single Dim sy As Single: Dim sx As Single Dim XLFilas As Single: Dim YLFilas As Single Dim XLCOlumnas As Single: Dim YLColumnas As Single Dim NumColumnas As Integer: Dim NumFilas As Integer: Dim SeparacionFilas As Single: Dim SeparacionColumnas As Single Dim Perdidas As Single: Dim rep As Integer Dim pasos As Integer 'Dia = txtDia.Text 'HoraDia = txtHora.Text Dim zrecta As Single Dim RA1 As Single: Dim RB1 As Single: Dim RC1 As Single Dim RA2 As Single: Dim RB2 As Single: Dim RC2 As Single Dim PerdidasNS As Single: Dim GananciasNS As Single Dim PerdidasEO As Single: Dim GananciasEO As Single Dim PerdidasNSprov As Single: Dim GananciasNSprov As Single Dim PerdidasEOprov As Single: Dim GananciasEOprov As Single PerdidasNS = 0 PerdidasEO = 0 'GananciasNS = 1 'GananciasEO = 1 Dia = 0 Dim Seguidor As Integer: Dim sc As Single: Dim AlturaPreal As Single Dim AreaPerdidas As Single: Dim AreaPerdidasTotal As Single: Dim AreaTotal As Single Dim DiaMes As Integer: Dim Mes As Integer: Dim FinMes As Integer Dim SeguidorNumero As Integer Dim XSEGFijo As Single: Dim YSEGFijo As Single Dim ApExcel As Variant Dim PorcPerdidas As Single 114 Set ApExcel = CreateObject("Excel.application") ' Hace que Excel se vea ApExcel.Visible = True 'Agrega un nuevo Libro ApExcel.workbooks.Add ApExcel.cells(1, 2).formula = "Enero" ApExcel.cells(1, 3).formula = "Febrero" ApExcel.cells(1, 4).formula = "Marzo" ApExcel.cells(1, 5).formula = "Abril" ApExcel.cells(1, 6).formula = "Mayo" ApExcel.cells(1, 7).formula = "Junio" ApExcel.cells(1, 8).formula = "Julio" ApExcel.cells(1, 9).formula = "Agosto" ApExcel.cells(1, 10).formula = "Septiembre" ApExcel.cells(1, 11).formula = "Octubre" ApExcel.cells(1, 12).formula = "Noviembre" ApExcel.cells(1, 13).formula = "Diciembre" ApExcel.range("b1:m1").Font.Size = 10 ApExcel.range("b1:m1").Font.Bold = True SeguidorNumero = 0 For a = 1 To ii For b = 1 To jj XSEGFijo = PoscSegX(a, b) YSEGFijo = PoscSegY(a, b) If XSEGFijo <> 0 Then SeguidorNumero = SeguidorNumero + 1 For Mes = 1 To 12 Select Case Mes Case 4, 6, 9, 11 115 FinMes = 30 Case 1, 3, 5, 7, 8, 10, 12 FinMes = 31 Case 2 FinMes = 28 End Select For DiaMes = 1 To FinMes Dia = Dia + 1 For Seguidor = 1 To 8 For HoraDia = 0 To 24 Step 0.5 Azimut = CalculoAngulos2(Dia, HoraDia) Altura = CalculoAngulos1(Dia, HoraDia) If Altura = 0 Then AreaPerdidas = 0 Area = 0 ElseIf HoraDia = 12 Then AreaPerdidas = 0 Area = BaseP * AlturaP Else If Seguidor = 5 Or Seguidor = 7 Then If a = ii Then basex = 0 basey = 0 ElseIf b = jj And Seguidor = 5 Then basex = 0 basey = 0 ElseIf b = 1 And Seguidor = 7 Then basex = 0 basey = 0 Else If Seguidor = 5 And Azimut < PI / 2 Then 116 basex = 0 basey = 0 ElseIf Seguidor = 7 And Azimut > PI / 2 Then basex = 0 basey = 0 Else If Seguidor = 5 Then sx = -PoscSegX(a + 1, b + 1) + XSEGFijo sy = -PoscSegY(a + 1, b + 1) + YSEGFijo ElseIf Seguidor = 7 Then sx = -PoscSegX(a + 1, b - 1) + XSEGFijo sy = -PoscSegY(a + 1, b - 1) + YSEGFijo End If If sx = 0 Then basex = 0 basey = 0 Else r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = (a2 * b3) - (a3 * b2) v2 = -((a1 * b3) - (a3 * b1)) v3 = (a1 * b2) - (a2 * b1) d = -s1 * v1 - s2 * v2 - s3 * v3 117 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) 'donde sf será la distancia de separación entre filas r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) 'Este s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 w1 = (a2 * b3) - (a3 * b2) w2 = -((a1 * b3) - (a3 * b1)) w3 = (a1 * b2) - (a2 * b1) e = -s1 * w1 - s2 * w2 - s3 * w3 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta < z Then basex = 0 basey = 0 Else If Azimut > PI / 2 And Seguidor = 5 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf Azimut < PI / 4 And Seguidor = 7 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) + sx 118 r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf PI / 2 > Azimut And Seguidor = 7 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 End If a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 u1 = (a2 * b3) - (a3 * b2) u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) 'Dim XLFilas As Single: Dim YLFilas As Single: Dim basex As Single: Dim basey As Single XLFilas = (X * Cos(Azimut)) + (Y * Sin(Azimut)) YLFilas = (-X * Sin(Azimut)) + (Y * Cos(Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then 119 If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut > PI / 2 And Seguidor = 5 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut < PI / 4 And Seguidor = 7 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf PI / 2 > Azimut And Seguidor = 7 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If End If End If End If End If End If If Seguidor = 8 Then If b = 1 Then basex = 0 basey = 0 ElseIf PoscSegX(a, b - 1) = 0 Then basex = 0 basey = 0 Else sx = -PoscSegX(a, b - 1) + XSEGFijo sy = -PoscSegY(a, b - 1) + YSEGFijo 120 r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = (a2 * b3) - (a3 * b2) v2 = -((a1 * b3) - (a3 * b1)) v3 = (a1 * b2) - (a2 * b1) d = -s1 * v1 - s2 * v2 - s3 * v3 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) 'donde sf será la distancia de separación entre filas r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) 'Este s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 w1 = (a2 * b3) - (a3 * b2) w2 = -((a1 * b3) - (a3 * b1)) w3 = (a1 * b2) - (a2 * b1) e = -s1 * w1 - s2 * w2 - s3 * w3 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. 121 X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta > z Then If Azimut >= 0 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf Azimut < 0 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) + sy t3 = 0 End If 'El plano va a ser de la forma: u1*x+u2*y+u3*z+f=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 u1 = (a2 * b3) - (a3 * b2) u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección 122 X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) 'Dim XLFilas As Single: Dim YLFilas As Single: Dim basex As Single: Dim basey As Single XLFilas = (X * Cos(Azimut)) + (Y * Sin(Azimut)) YLFilas = (-X * Sin(Azimut)) + (Y * Cos(Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut >= 0 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut < 0 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If End If End If If Seguidor = 6 Then If a = ii Then basex = 0 basey = 0 ElseIf PoscSegX(a + 1, b) = 0 Then basex = 0 123 basey = 0 Else sx = -PoscSegX(a + 1, b) + XSEGFijo sy = -PoscSegY(a + 1, b) + YSEGFijo r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = (a2 * b3) - (a3 * b2) v2 = -((a1 * b3) - (a3 * b1)) v3 = (a1 * b2) - (a2 * b1) d = -s1 * v1 - s2 * v2 - s3 * v3 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) sf será la distancia de separación entre filas r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) 'Este 'donde s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 w1 = (a2 * b3) - (a3 * b2) w2 = -((a1 * b3) - (a3 * b1)) w3 = (a1 * b2) - (a2 * b1) e = -s1 * w1 - s2 * w2 - s3 * w3 124 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta > z Then If Azimut < PI / 2 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) t3 = 0 ElseIf Azimut >= PI / 2 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) t3 = 0 End If 'El plano va a ser de la forma: u1*x+u2*y+u3*z+f=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 u1 = (a2 * b3) - (a3 * b2) u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 125 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) XLFilas = (X * Cos(Azimut)) + (Y * Sin(Azimut)) YLFilas = (-X * Sin(Azimut)) + (Y * Cos(Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut >= PI / 2 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut < PI / 2 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If End If End If If Seguidor = 2 Then If a = 1 Then basex = 0 basey = 0 ElseIf PoscSegX(a - 1, b) = 0 Then basex = 0 126 basey = 0 Else sx = -PoscSegX(a - 1, b) + XSEGFijo sy = -PoscSegY(a - 1, b) + YSEGFijo 'INTERSECCIÓN ENTRE 2 PLANOS 'ECUACIÓN DEL PLANO '3 PUNTOS 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = ((a2 * b3) - (a3 * b2)) v2 = -((a1 * b3) - (a3 * b1)) v3 = ((a1 * b2) - (a2 * b1)) d = -s1 * v1 - s2 * v2 - s3 * v3 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) sf será la distancia de separación entre filas r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) 'Este 'donde s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 127 w1 = ((a2 * b3) - (a3 * b2)) w2 = -((a1 * b3) - (a3 * b1)) w3 = ((a1 * b2) - (a2 * b1)) e = -s1 * w1 - s2 * w2 - s3 * w3 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta > z Then If Azimut > -PI / 2 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) t3 = 0 ElseIf Azimut <= -PI / 2 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) t3 = 0 End If 'El plano va a ser de la forma: u1*x+u2*y+u3*z+f=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 u1 = (a2 * b3) - (a3 * b2) 128 u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) XLFilas = (X * Cos(-Azimut)) + (Y * Sin(-Azimut)) YLFilas = (-X * Sin(-Azimut)) + (Y * Cos(-Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut > -PI / 2 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut <= -PI / 2 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If End If End If If Seguidor = 3 Or Seguidor = 1 Then 129 If a = 1 Then basex = 0 basey = 0 ElseIf b = 1 And Seguidor = 1 Then basex = 0 basey = 0 ElseIf b = jj And Seguidor = 3 Then basex = 0 basey = 0 Else If Seguidor = 3 And Azimut > -PI / 2 Then basex = 0 basey = 0 ElseIf Seguidor = 1 And Azimut < -PI / 2 Then basex = 0 basey = 0 Else If Seguidor = 3 Then sx = -PoscSegX(a - 1, b + 1) + XSEGFijo sy = -PoscSegY(a - 1, b + 1) + YSEGFijo ElseIf Seguidor = 1 Then sx = -PoscSegX(a - 1, b - 1) + XSEGFijo sy = -PoscSegY(a - 1, b - 1) + YSEGFijo End If If sx = 0 Then basex = 0 basey = 0 Else r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx 130 s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = (a2 * b3) - (a3 * b2) v2 = -((a1 * b3) - (a3 * b1)) v3 = (a1 * b2) - (a2 * b1) d = -s1 * v1 - s2 * v2 - s3 * v3 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) 'donde sf será la distancia de separación entre filas r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) 'Este s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 w1 = (a2 * b3) - (a3 * b2) w2 = -((a1 * b3) - (a3 * b1)) w3 = (a1 * b2) - (a2 * b1) e = -s1 * w1 - s2 * w2 - s3 * w3 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta < z Then 131 'AreaPerdidas = 0 basex = 0 basey = 0 Else If Azimut < -PI / 2 And Seguidor = 3 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf Azimut > -PI / 4 And Seguidor = 1 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf -PI / 2 < Azimut And Seguidor = 1 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) + sx r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) + sx s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) + sx t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) + sy t3 = 0 End If a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 132 u1 = (a2 * b3) - (a3 * b2) u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) 'Dim XLFilas As Single: Dim YLFilas As Single: Dim basex As Single: Dim basey As Single XLFilas = (X * Cos(Azimut)) + (Y * Sin(Azimut)) YLFilas = (-X * Sin(Azimut)) + (Y * Cos(Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut < -PI / 2 And Seguidor = 3 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut > -PI / 4 And Seguidor = 1 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf -PI / 2 < -Azimut And Seguidor = 1 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 133 End If End If End If End If End If End If If Seguidor = 4 Then If b = jj Then basex = 0 basey = 0 ElseIf PoscSegX(a, b + 1) = 0 Then basex = 0 basey = 0 Else sx = -PoscSegX(a, b + 1) + XSEGFijo sy = -PoscSegY(a, b + 1) + YSEGFijo r1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy t3 = 0 'El plano va a ser de la forma: v1*x+v2*y+v3*z+d=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 v1 = (a2 * b3) - (a3 * b2) v2 = -((a1 * b3) - (a3 * b1)) v3 = (a1 * b2) - (a2 * b1) d = -s1 * v1 - s2 * v2 - s3 * v3 'vuelvo a definir 3 puntos 'R=(r1, r2, r3) S=(s1, s2, s3) T=(t1, t2, t3) r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) plano corresponde al segundo seguidor r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) 'donde sf será la distancia de separación entre filas 'Este 134 r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) t3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 'El plano va a ser de la forma: w1*x+w2*y+w3*z+e=0 w1 = (a2 * b3) - (a3 * b2) w2 = -((a1 * b3) - (a3 * b1)) w3 = (a1 * b2) - (a2 * b1) e = -s1 * w1 - s2 * w2 - s3 * w3 'Luego la recta intersección vendrá definida por: v1*x+v2*y+v3*z+d=0 y w1*x+w2*y+w3*z+e=0 'voy a comprobar que la sombra de un seguidor interseca con el otro 'para ello, voy a comparar alturas. X = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) z = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) zrecta = -(((v1 - (w1 * v2 / w2)) * X) + (d - (e * v2 / w2))) / (v3 - (w3 * v2 / w2)) If zrecta > z Then If Azimut < 0 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 1, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 1, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 1, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 2, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 2, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 2, 1, AlturaColumna, AngMax) + sy t3 = 0 ElseIf Azimut >= 0 Then r1 = LocalesAGlobales(Dia, HoraDia, 1, 4, 0, AlturaColumna, AngMax) r2 = LocalesAGlobales(Dia, HoraDia, 2, 4, 0, AlturaColumna, AngMax) + sy r3 = LocalesAGlobales(Dia, HoraDia, 3, 4, 0, AlturaColumna, AngMax) s1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 0, AlturaColumna, AngMax) s2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 0, AlturaColumna, AngMax) + sy s3 = LocalesAGlobales(Dia, HoraDia, 3, 3, 0, AlturaColumna, AngMax) t1 = LocalesAGlobales(Dia, HoraDia, 1, 3, 1, AlturaColumna, AngMax) t2 = LocalesAGlobales(Dia, HoraDia, 2, 3, 1, AlturaColumna, AngMax) + sy 135 t3 = 0 End If 'El plano va a ser de la forma: u1*x+u2*y+u3*z+f=0 a1 = s1 - t1: a2 = s2 - t2: a3 = s3 - t3 b1 = t1 - r1: b2 = t2 - r2: b3 = t3 - r3 u1 = (a2 * b3) - (a3 * b2) u2 = -((a1 * b3) - (a3 * b1)) u3 = (a1 * b2) - (a2 * b1) f = -s1 * u1 - s2 * u2 - s3 * u3 'Luego la recta intersección vendrá definida por: u1*x+u2*y+u3*z+f=0 y w1*x+w2*y+w3*z+e=0 RA1 = v1 - (v3 * w1 / w3): RB1 = v2 - (v3 * w2 / w3): RC1 = d - (v3 * e / w3) RA2 = u1 - (u3 * w1 / w3): RB2 = u2 - (u3 * w2 / w3): RC2 = f - (u3 * e / w3) 'hallo x e y de la intersección X = ((RB1 * RC2 / RB2) - RC1) / (RA1 - (RB1 * RA2 / RB2)) Y = -(((RA2 * X) + RC2) / RB2) 'Dim XLFilas As Single: Dim YLFilas As Single: Dim basex As Single: Dim basey As Single XLFilas = (X * Cos(Azimut)) + (Y * Sin(Azimut)) YLFilas = (-X * Sin(Azimut)) + (Y * Cos(Azimut)) AlturaPreal = YLSeguidor(Dia, HoraDia, 1, 0, AlturaColumna, AngMax) If BaseP / 2 > XLFilas And XLFilas > -BaseP / 2 Then If AlturaPreal > YLFilas And YLFilas > -AlturaPreal Then If Azimut < 0 Then basex = BaseP / 2 + XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) ElseIf Azimut >= 0 Then basex = BaseP / 2 - XLFilas basey = (AlturaP / 2) - ((YLFilas) / Cos(AnguloNormal)) End If Else basex = 0 basey = 0 End If 136 Else basex = 0 basey = 0 End If Else basex = 0 basey = 0 End If End If End If AreaPerdidas = basex * basey Area = BaseP * AlturaP AreaPerdidasTotal = AreaPerdidasTotal + AreaPerdidas AreaTotal = AreaTotal + Area End If Next Next Next PorcPerdidas = (AreaPerdidasTotal / AreaTotal) ApExcel.cells(SeguidorNumero + 1, 1).formula = "Seguidor" & SeguidorNumero ApExcel.cells(SeguidorNumero + 1, 1).Font.Size = 10 ApExcel.cells(SeguidorNumero + 1, 1).Font.Bold = True ApExcel.cells(SeguidorNumero + 1, Mes + 1).formula = PorcPerdidas ApExcel.cells(SeguidorNumero + 1, Mes + 1).Style = "Percent" ApExcel.cells(SeguidorNumero + 1, Mes + 1).NumberFormat = "0.00%" AreaPerdidasTotal = 0 AreaTotal = 0 Next Dia = 0 End If Next Next Set ApExcel = Nothing If NumerodeSeguidores = SeguidorNumero Then fin = 1 Else fin = 0 Numseguidores = Numseguidores + 1 ApExcel.workbooks.Close savechanges:=False 137 End If Loop Until fin = 1 End Sub Private Sub Form_Load() cmbComunidad.AddItem "Alava" cmbComunidad.AddItem "Albacete" cmbComunidad.AddItem "Alicante" cmbComunidad.AddItem "Almería" cmbComunidad.AddItem "Asturias" cmbComunidad.AddItem "Avila" cmbComunidad.AddItem "Badajoz" cmbComunidad.AddItem "Baleares" cmbComunidad.AddItem "Barcelona" cmbComunidad.AddItem "Burgos" cmbComunidad.AddItem "Cáceres" cmbComunidad.AddItem "Cádiz" cmbComunidad.AddItem "Cantabria" cmbComunidad.AddItem "Castellón" cmbComunidad.AddItem "Ceuta" cmbComunidad.AddItem "Ciudad Real" cmbComunidad.AddItem "Córdoba" cmbComunidad.AddItem "La Coruña" cmbComunidad.AddItem "Cuenca" cmbComunidad.AddItem "Gerona" cmbComunidad.AddItem "Granada" cmbComunidad.AddItem "Guadalajara" cmbComunidad.AddItem "Guipuzcoa" cmbComunidad.AddItem "Huelva" cmbComunidad.AddItem "Huesca" 138 cmbComunidad.AddItem "Jaén" cmbComunidad.AddItem "León" cmbComunidad.AddItem "Lérida" cmbComunidad.AddItem "Lugo" cmbComunidad.AddItem "Madrid" cmbComunidad.AddItem "Málaga" cmbComunidad.AddItem "Melilla" cmbComunidad.AddItem "Murcia" cmbComunidad.AddItem "Navarra" cmbComunidad.AddItem "Orense" cmbComunidad.AddItem "Palencia" cmbComunidad.AddItem "Las Palmas" cmbComunidad.AddItem "Pontevedra" cmbComunidad.AddItem "La Rioja" cmbComunidad.AddItem "Salamanca" cmbComunidad.AddItem "Sta. Cruz de Tenerife" cmbComunidad.AddItem "Segovia" cmbComunidad.AddItem "Sevilla" cmbComunidad.AddItem "Soria" cmbComunidad.AddItem "Tarragona" cmbComunidad.AddItem "Teruel" cmbComunidad.AddItem "Toledo" cmbComunidad.AddItem "Valencia" cmbComunidad.AddItem "Valladolid" cmbComunidad.AddItem "Vizcaya" cmbComunidad.AddItem "Zamora" cmbComunidad.AddItem "Zaragoza" End Sub 139