Example #1
0
        private List <IIlluminationArea> CalcIllumsByHeight(List <MapBuilding> buildings, double height)
        {
            List <IIlluminationArea> illumShadows = new List <IIlluminationArea>();

            using (Line lineShadow = GetLineShadow(height))
            {
                // перебор домов одной высоты
                foreach (var build in buildings)
                {
                    // Если дом полностью выше линии тени (сечения), то он полностью затеняет точку
                    if (build.YMin >= (lineShadow.StartPoint.Y - 0.1))
                    {
                        // Найти точку начала тени и конца (с минимальным и макс углом к точке расчета)
                        var ilumShadow = GetBuildingZeroLineShadows(build);
                        //var ilumShadow = GetIllumShadow(build.Contour.GetPoints().Where(p=>p.Y<ptCalc.Y).ToList());
                        if (ilumShadow != null)
                        {
                            illumShadows.Add(ilumShadow);
                        }
                    }
                    else if (build.YMax >= (lineShadow.StartPoint.Y - 0.1))
                    {
                        var ilumsBoundary = GetBuildingLineShadowBoundary(build, lineShadow, Intersect.ExtendThis);
                        illumShadows.AddRange(ilumsBoundary);
                    }
                }
#if TEST
                EntityHelper.AddEntityToCurrentSpace(lineShadow);
#endif
            }
            // Объединение совпадающих зон теней
            illumShadows = IllumAreaBase.Merge(illumShadows);
            return(illumShadows);
        }
Example #2
0
        public List <IIlluminationArea> Calc()
        {
            var resAreas = new List <IIlluminationArea>();

            // Корректировка расчетной точки
            if (!CorrectCalcPoint())
            {
                return(null);
            }

            // Проверка - если точка расположена внутри другого дома (кроме собственного), то вся точка в тени
            if (IsCalcPointInsideOtherBuilding())
            {
                throw new Exception("Расчтеная точка попадает на соседнее здание.");
                //return null;
            }

            // Определение ограничений углов (начального и конечного) с учетом плоскости стены расчетного дома
            if (DefineStartAnglesByOwnerBuilding())
            {
                // расчетные граници (по заданным расчетным углам)
                var ext = GetCalcExtents(map.MaxBuildingHeight);
                // кусок карты
                using (var scope = map.GetScope(ext))
                {
                    // исключение из списка домов собственно расчетного дома
                    if (buildingOwner != null)
                    {
                        scope.Buildings.Remove(buildingOwner);
                    }

                    // Добавление отсеченных частей здания от собственного здания расчетной точки
                    if (secantBuildings != null)
                    {
                        foreach (var item in secantBuildings)
                        {
                            item.InitContour();
                        }
                        scope.Buildings.AddRange(secantBuildings);
                    }

                    // Расчет зон теней
                    // группировка домов по высоте
                    var    heights      = scope.Buildings.GroupBy(g => g.HeightCalc);
                    double ptHeightCalc = GetPtCalcHeight();
                    foreach (var bHeight in heights)
                    {
                        double heightCalc = GetHeightCalcBuilding(ptHeightCalc, bHeight.Key);
                        if (heightCalc == 0)
                        {
                            continue;
                        }
                        var illumsByHeight = CalcIllumsByHeight(bHeight.ToList(), heightCalc);
                        if (illumsByHeight != null && illumsByHeight.Any())
                        {
                            resAreas.AddRange(illumsByHeight);
                        }
                    }
                }
                resAreas = IllumAreaBase.Merge(resAreas);

                // Инвертировать зоны теней в зоны освещенностей
                resAreas = IllumAreaCentral.Invert(resAreas, StartAnglesIllum, ptCalc2d, insPt);
            }
            else
            {
                StartAnglesIllum.AngleEndOnPlane   = 0;
                StartAnglesIllum.AngleStartOnPlane = 0;
            }
            return(resAreas);
        }