Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
114c6a5989 | ||
|
|
b09f45f594 |
@@ -1,5 +1,5 @@
|
||||
import sys
|
||||
from math import sqrt, atan, degrees
|
||||
from math import sqrt, degrees, acos
|
||||
from helix.models.corner import Corner
|
||||
from helix.constants.global_constants import max_corner_angle
|
||||
import flask_featureflags as feature
|
||||
@@ -76,43 +76,42 @@ class ProjectPresenter(object):
|
||||
return result
|
||||
|
||||
def get_corners(self, buildings):
|
||||
|
||||
def angle(x1, y1, x2, y2):
|
||||
# Use dotproduct to find angle between vectors
|
||||
# This always returns an angle between 0, pi
|
||||
numer = (x1 * x2 + y1 * y2)
|
||||
denom = sqrt((x1 ** 2 + y1 ** 2) * (x2 ** 2 + y2 ** 2))
|
||||
return acos(numer / denom)
|
||||
|
||||
|
||||
def cross_sign(x1, y1, x2, y2):
|
||||
# True if cross is positive
|
||||
# False if negative or zero
|
||||
return x1 * y2 > x2 * y1
|
||||
|
||||
result = []
|
||||
if feature.is_active('ff_cpp'):
|
||||
for building in buildings:
|
||||
presentable_building = []
|
||||
result.append(presentable_building)
|
||||
previous_corner = building[-1]
|
||||
for i, corner in enumerate(building):
|
||||
if (i+1 == len(building)):
|
||||
next_corner = building[0]
|
||||
else:
|
||||
next_corner = building[i+1]
|
||||
|
||||
#x coordinate is stored as first element of corner variable
|
||||
#y coordinate is stored as second element of corner variable
|
||||
corner_length_ccw = sqrt((next_corner[0] - corner[0])**2 + (next_corner[1] - corner[1])**2)
|
||||
corner_length_cw = sqrt((previous_corner[0] - corner[0])**2 + (previous_corner[1] - corner[1])**2)
|
||||
|
||||
k1 = float('Inf') if (corner[0]==previous_corner[0]) else (corner[1] - previous_corner[1]) / (corner[0] - previous_corner[0])
|
||||
k2 = float('Inf') if (corner[0]==next_corner[0]) else (next_corner[1] - corner[1]) / (next_corner[0] - corner[0])
|
||||
for building in buildings:
|
||||
presentable_building = []
|
||||
result.append(presentable_building)
|
||||
|
||||
for i in range(len(building)):
|
||||
p1 = building[i]
|
||||
ref = building[i - 1]
|
||||
p2 = building[i - 2]
|
||||
x1, y1 = p1[0] - ref[0], p1[1] - ref[1]
|
||||
x2, y2 = p2[0] - ref[0], p2[1] - ref[1]
|
||||
|
||||
theta2 = degrees(atan(k2))
|
||||
theta1 = degrees(atan(k1)) - theta2
|
||||
|
||||
if (theta1 < 0):
|
||||
if (k1 < 0 and k2 < 0):
|
||||
theta1 = 360 + theta1
|
||||
elif (k1 <= 0 and k2 >= 0):
|
||||
theta1 = 180 + theta1
|
||||
else:
|
||||
if (k1 > 0 and k2 > 0):
|
||||
theta1 = 180 + theta1
|
||||
|
||||
if (theta1 < max_corner_angle):
|
||||
presentable_building.append(Corner(corner[0], corner[1], corner_length_ccw,corner_length_cw, theta1).__dict__)
|
||||
|
||||
previous_corner = corner
|
||||
corner_length_cw = sqrt(x2**2 + y2**2)
|
||||
corner_length_ccw = sqrt(x1**2 + y1**2)
|
||||
theta = degrees(angle(x1, y1, x2, y2))
|
||||
|
||||
#print('Points', p1, ref, p2)
|
||||
#print('Angle', theta)
|
||||
if (cross_sign(x1, y1, x2, y2)) and (theta < max_corner_angle) :
|
||||
#print('Inner Angle')
|
||||
presentable_building.append(Corner(ref[0], ref[1], corner_length_ccw,corner_length_cw, theta).__dict__)
|
||||
return result
|
||||
|
||||
def get_max_y(self,buildings, panels):
|
||||
|
||||
@@ -81,15 +81,27 @@ class PanelPresenterTest(unittest.TestCase):
|
||||
actual_buildings = self.subject.get_buildings(buildings,60)
|
||||
assert_array_equal(actual_buildings,expected_buildings)
|
||||
|
||||
def test_get_corners_fancy_building(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ [2, 5], [2, 3], [0,3], [0, 0], [2,0], [2,-3], [6,-3], [8,-1], [8,1], [6,3], [4,3], [4,5] ] ] # fancy builgin with three interior corners
|
||||
expected_corners = [[
|
||||
{'length_ccw': 2.0, 'angle': 90.0, 'y': 5, 'x': 4, 'length_cw': 2.0},
|
||||
{'length_ccw': 2.0, 'angle': 90.0, 'y': 5, 'x': 2, 'length_cw': 2.0},
|
||||
{'length_ccw': 3.0, 'angle': 90.0, 'y': 3, 'x': 0, 'length_cw': 2.0},
|
||||
{'length_ccw': 2.0, 'angle': 90.0, 'y': 0, 'x': 0, 'length_cw': 3.0},
|
||||
{'length_ccw': 4.0, 'angle': 90.0, 'y': -3, 'x': 2, 'length_cw': 3.0}]]
|
||||
actual_corners = self.subject.get_corners(buildings)
|
||||
assert_array_equal(actual_corners,expected_corners)
|
||||
|
||||
#@mock.patch('flask_featureflags.is_active',side_effect=feature_is_always_active)
|
||||
def test_get_corners_box_building(self):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ [0, 0], [60, 0], [60,60], [0, 60] ] ] # big square
|
||||
expected_corners = [[
|
||||
{'x': 0, 'y': 60, 'length_cw': 60, 'length_ccw':60, 'angle':90},
|
||||
{'x': 0, 'y': 0, 'length_cw': 60, 'length_ccw':60, 'angle':90},
|
||||
{'x': 60, 'y': 0, 'length_cw': 60, 'length_ccw':60, 'angle':90},
|
||||
{'x': 60, 'y': 60, 'length_cw': 60, 'length_ccw':60, 'angle':90},
|
||||
{'x': 0, 'y': 60, 'length_cw': 60, 'length_ccw':60, 'angle':90}
|
||||
{'x': 60, 'y': 60, 'length_cw': 60, 'length_ccw':60, 'angle':90}
|
||||
]]
|
||||
actual_corners = self.subject.get_corners(buildings)
|
||||
assert_array_equal(actual_corners,expected_corners)
|
||||
@@ -99,10 +111,10 @@ class PanelPresenterTest(unittest.TestCase):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ [0, 0], [51.96, 30], [21.96, 81.96], [-30, 51.96] ] ] # big square
|
||||
expected_corners = [[
|
||||
{'x': -30, 'y': 51.96, 'length_cw': 59.998679985479676, 'length_ccw':59.99867998547968, 'angle':90},
|
||||
{'x': 0, 'y': 0, 'length_cw': 59.99867998547968, 'length_ccw':59.99867998547968, 'angle':90},
|
||||
{'x': 51.96, 'y': 30, 'length_cw': 59.99867998547968, 'length_ccw':59.998679985479676, 'angle':90},
|
||||
{'x': 21.96, 'y': 81.96, 'length_cw': 59.998679985479676, 'length_ccw':59.998679985479676, 'angle':90},
|
||||
{'x': -30, 'y': 51.96, 'length_cw': 59.998679985479676, 'length_ccw':59.99867998547968, 'angle':90}
|
||||
{'x': 21.96, 'y': 81.96, 'length_cw': 59.998679985479676, 'length_ccw':59.998679985479676, 'angle':90.00000000000001}
|
||||
]]
|
||||
actual_corners = self.subject.get_corners(buildings)
|
||||
assert_array_equal(actual_corners,expected_corners)
|
||||
@@ -112,10 +124,10 @@ class PanelPresenterTest(unittest.TestCase):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ [-3.42, 1.51], [-1.66, -1.64], [4.22, -0.87], [-0.8, 5.64]] ]
|
||||
expected_corners = [[
|
||||
{'x': -0.8, 'y': 5.64, 'length_cw': 8.22073597678456, 'length_ccw':4.890940604832571, 'angle':70.02691327912069},
|
||||
{'x': -3.42, 'y': 1.51, 'length_cw': 4.890940604832571, 'length_ccw':3.6083375673570233, 'angle':118.41626123074676},
|
||||
{'x': -1.66, 'y': -1.64, 'length_cw': 3.6083375673570233, 'length_ccw':5.930202357424239, 'angle':111.73284308914215},
|
||||
{'x': 4.22, 'y': -0.87, 'length_cw': 5.930202357424239, 'length_ccw':8.22073597678456, 'angle':59.823982400990424},
|
||||
{'x': -0.8, 'y': 5.64, 'length_cw': 8.22073597678456, 'length_ccw':4.890940604832571, 'angle':70.02691327912069}
|
||||
{'x': -1.66, 'y': -1.64, 'length_cw': 3.6083375673570233, 'length_ccw':5.930202357424239, 'angle':111.73284308914216},
|
||||
{'x': 4.22, 'y': -0.87, 'length_cw': 5.930202357424239, 'length_ccw':8.22073597678456, 'angle':59.82398240099042}
|
||||
]]
|
||||
actual_corners = self.subject.get_corners(buildings)
|
||||
assert_array_equal(actual_corners,expected_corners)
|
||||
@@ -125,14 +137,13 @@ class PanelPresenterTest(unittest.TestCase):
|
||||
self.subject = ProjectPresenter(SystemType.singleTilt, ModuleType.Cell96)
|
||||
buildings = [ [ [-3.58, 3.32], [-0.78, -2.9], [-1.56,0.88], [0.66, -2.16], [1.5, 1.16], [2.72, 2.36], [-0.8, 5.64] ] ]
|
||||
expected_corners = [[
|
||||
{'x': -0.8, 'y': 5.64, 'length_cw': 4.811319985201567, 'length_ccw':3.6208838699963852, 'angle':97.17527350158385},
|
||||
{'x': -3.58, 'y': 3.32, 'length_cw': 3.6208838699963852, 'length_ccw':6.821172919667115, 'angle':105.6106862572924},
|
||||
{'x': -0.78, 'y': -2.9, 'length_cw': 6.821172919667115, 'length_ccw':3.8596372886580936, 'angle':12.576112527956795},
|
||||
{'x': 0.66, 'y': -2.16, 'length_cw': 3.7643060449437424, 'length_ccw':3.424616766880639, 'angle':50.33783308603299},
|
||||
{'x': 2.72, 'y': 2.36, 'length_cw': 1.7112568480505783, 'length_ccw':4.811319985201567, 'angle':87.50512700090906},
|
||||
{'x': -0.8, 'y': 5.64, 'length_cw': 4.811319985201567, 'length_ccw':3.6208838699963852, 'angle':97.17527350158382}
|
||||
{'x': -0.78, 'y': -2.9, 'length_cw': 6.821172919667115, 'length_ccw':3.8596372886580936, 'angle':12.576112527956782},
|
||||
{'x': 0.66, 'y': -2.16, 'length_cw': 3.7643060449437424, 'length_ccw':3.424616766880639, 'angle':50.337833086033},
|
||||
{'x': 2.72, 'y': 2.36, 'length_cw': 1.7112568480505783, 'length_ccw':4.811319985201567, 'angle':87.50512700090906}
|
||||
]]
|
||||
actual_corners = self.subject.get_corners(buildings)
|
||||
print(actual_corners)
|
||||
assert_array_equal(actual_corners,expected_corners)
|
||||
|
||||
def test_get_max_y(self):
|
||||
|
||||
Reference in New Issue
Block a user