diff --git a/src/RevitOpeningPlacement/Models/OpeningUnion/OpeningsGroup.cs b/src/RevitOpeningPlacement/Models/OpeningUnion/OpeningsGroup.cs index e1a391b7d..d972a8776 100644 --- a/src/RevitOpeningPlacement/Models/OpeningUnion/OpeningsGroup.cs +++ b/src/RevitOpeningPlacement/Models/OpeningUnion/OpeningsGroup.cs @@ -145,19 +145,44 @@ private bool IsTouchingOpening(OpeningMepTaskOutcoming otherOpeningTask) { private bool OpeningsLocatedOnTheSameLine(OpeningMepTaskOutcoming otherOpeningTask) { if(_elements.Count == 0) { return true; } if(_elements.Count == 1) { - var firstNormal = _elements.First().GetFamilyInstance().FacingOrientation; + var firstOrientation = _elements.First().GetFamilyInstance().FacingOrientation; + var secondOrientation = otherOpeningTask.GetFamilyInstance().FacingOrientation; + if(!firstOrientation.IsAlmostEqualTo(secondOrientation)) { + return false; + } + + var firstHandOrientation = _elements.First().GetFamilyInstance().HandOrientation; var firstLocation = _elements.First().Location; var secondLocation = otherOpeningTask.Location; var direction = (secondLocation - firstLocation).Normalize(); - return firstNormal.IsAlmostEqualTo(direction) || firstNormal.IsAlmostEqualTo(direction.Negate()); + return AngleIsMultiplyOf(firstOrientation.AngleTo(direction), Math.PI / 2) + && AngleIsMultiplyOf(firstHandOrientation.AngleTo(direction), Math.PI / 2); } else { var firstToOtherDirection = GetDirectionBetween(_elements.First(), otherOpeningTask); var lastToOtherDirection = GetDirectionBetween(_elements.Last(), otherOpeningTask); double angle = firstToOtherDirection.AngleTo(lastToOtherDirection); - bool angleIsZero = Math.Round(angle, 9) == 0; - bool angleIsPi = Math.Round(angle - Math.PI, 9) == 0; - return angleIsZero || angleIsPi; + return AngleIsMultiplyOf(angle, Math.PI); + } + } + + /// + /// Проверяет, что заданный угол кратен другому углу + /// + /// Угол для проверки + /// Угол, которому должен быть кратен первый + /// Точность сравнения углов + /// True, если первый угол кратен второму + private bool AngleIsMultiplyOf(double angle, double multiplyAngle, double epsilon = 1e-9) { + if(Math.Abs(angle) <= epsilon) { + return true; } + + if(Math.Abs(angle - multiplyAngle) <= epsilon) { + return true; + } + + double reminder = Math.Abs(angle % multiplyAngle); + return reminder <= epsilon || Math.Abs(reminder - multiplyAngle) <= epsilon; } ///