Module: BTAP::Geometry::Surfaces
- Defined in:
- lib/openstudio-standards/btap/geometry.rb
Class Method Summary collapse
- .create_surface(model, name, os_point3d_array, boundary_condition = "", construction = "") ⇒ Object
-
.filter_by_azimuth_and_tilt(surfaces, azimuth_from, azimuth_to, tilt_from, tilt_to, tolerance = 1.0) ⇒ Object
Azimuth start from Y axis, Tilts starts from Z-axis.
- .filter_by_boundary_condition(surfaces, boundary_conditions) ⇒ Object
- .filter_by_interzonal_surface(surfaces) ⇒ Object
- .filter_by_non_defaulted_surfaces(surfaces) ⇒ Object
- .filter_by_surface_types(surfaces, surfaceTypes) ⇒ Object
-
.filter_subsurfaces_by_types(subsurfaces, subSurfaceTypes) ⇒ Object
[“FixedWindow” , “OperableWindow” , “Door” , “GlassDoor”, “OverheadDoor” , “Skylight”, “TubularDaylightDiffuser”,“TubularDaylightDome”].
-
.get_overlapping_segments(overlap_segs:, index:, point_a1:, point_a2:) ⇒ Object
This method takes the y projections of a bunch of overlapping line segments and sorts them to determines which are unique and, if they are not unique, which is closest to the current, upwardly pointing, line.
-
.getSurfaceAreafromVertices(vertices:) ⇒ Object
This method calculates the surface area of a 2-D polygon from an array of OpenStudio vertices.
- .hide(surfaces) ⇒ Object
-
.line_segment_overlap_x_coord(y_check:, point_b1:, point_b2:) ⇒ Object
This method determines the x coordinate of where a given y coordinate crosses a given line.
-
.line_segment_overlap_y?(point_a1:, point_a2:, point_b1:, point_b2:) ⇒ Boolean
This method determines if the y component of 2 lines overlap.
-
.make_convex_surfaces(surface:, tol: 12) ⇒ Object
2018-09-27 Chris Kirney This method takes a surface in the x-y plane (z coordinates are ignored) with an upwardly pointing normal and turns it into convex quadrialaterals.
-
.rotate_tilt_translate_surfaces(planar_surfaces, azimuth_degrees, tilt_degrees = 0.0, translation_vector = OpenStudio::Vector3d.new(0.0, 0.0, 0.0)) ⇒ OpenStudio::Model::Model
This method will rotate a surface.
- .set_fenestration_to_wall_ratio(surfaces, ratio, offset = 0, height_offset_from_floor = true, floor = "all") ⇒ Object
-
.set_surfaces_boundary_condition(model, surfaces, boundaryCondition) ⇒ Object
This method sets the boundary condition for a surface and it’s matching surface.
-
.set_surfaces_construction_conductance(surfaces, conductance) ⇒ Object
This method creates a new construction based on the current, changes the rsi and assign the construction to the current surface.
- .show(surfaces) ⇒ Object
-
.subdivide_overlaps(overlap_segs:) ⇒ Object
This method was originally written to work with the ‘make_concave_surfaces’ method above.
-
.surf_centroid(surf:) ⇒ Object
This method finds the centroid of a surface using the point averaging method.
Class Method Details
.create_surface(model, name, os_point3d_array, boundary_condition = "", construction = "") ⇒ Object
549 550 551 552 553 554 555 556 557 558 559 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 549 def self.create_surface(model, name, os_point3d_array, boundary_condition = "", construction = "") os_surface = OpenStudio::Model::Surface.new(os_point3d_array, model) os_surface.setName(name) if OpenStudio::Model::Surface::validOutsideBoundaryConditionValues.include?(boundary_condition) self.set_surfaces_boundary_condition([os_surface], boundary_condition) else puts "boundary condition not set for #{name}" end os_surface.setConstruction(construction) return os_surface end |
.filter_by_azimuth_and_tilt(surfaces, azimuth_from, azimuth_to, tilt_from, tilt_to, tolerance = 1.0) ⇒ Object
Azimuth start from Y axis, Tilts starts from Z-axis
743 744 745 746 747 748 749 750 751 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 743 def self.filter_by_azimuth_and_tilt(surfaces, azimuth_from, azimuth_to, tilt_from, tilt_to, tolerance = 1.0) return_surfaces = [] surfaces.each do |surface| unless OpenStudio::Model::PlanarSurface::findPlanarSurfaces([surface], OpenStudio::OptionalDouble.new(azimuth_from), OpenStudio::OptionalDouble.new(azimuth_to), OpenStudio::OptionalDouble.new(tilt_from), OpenStudio::OptionalDouble.new(tilt_to), tolerance).empty? return_surfaces << surface end end return return_surfaces end |
.filter_by_boundary_condition(surfaces, boundary_conditions) ⇒ Object
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 674 def self.filter_by_boundary_condition(surfaces, boundary_conditions) #check to see if a string or an array was passed. if boundary_conditions.kind_of?(String) temp = boundary_conditions boundary_conditions = Array.new() boundary_conditions.push(temp) end #ensure boundary conditions are valid boundary_conditions.each do |boundary_condition| unless OpenStudio::Model::Surface::validOutsideBoundaryConditionValues.include?(boundary_condition) raise "ERROR: Invalid Boundary Condition = " + boundary_condition + "Correct Values are:" + OpenStudio::Model::Surface::validOutsideBoundaryConditionValues.to_s end end #create return array. return_array = Array.new() if boundary_conditions.size == 0 or boundary_conditions[0].upcase == "All".upcase return_array = surfaces else surfaces.each do |surface| boundary_conditions.each do |condition| if surface.outsideBoundaryCondition == condition return_array.push(surface) end end end end return return_array end |
.filter_by_interzonal_surface(surfaces) ⇒ Object
732 733 734 735 736 737 738 739 740 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 732 def self.filter_by_interzonal_surface(surfaces) return_array = Array.new() surfaces.each do |surface| unless surface.adjacentSurface().empty? return_array.push(surface) end return return_array end end |
.filter_by_non_defaulted_surfaces(surfaces) ⇒ Object
668 669 670 671 672 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 668 def self.filter_by_non_defaulted_surfaces(surfaces) non_defaulted_surfaces = Array.new() surfaces.each {|surface| non_defaulted_surfaces << surface unless surface.isConstructionDefaulted} return non_defaulted_surfaces end |
.filter_by_surface_types(surfaces, surfaceTypes) ⇒ Object
704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 704 def self.filter_by_surface_types(surfaces, surfaceTypes) #check to see if a string or an array was passed. if surfaceTypes.kind_of?(String) temp = surfaceTypes surfaceTypes = Array.new() surfaceTypes.push(temp) end surfaceTypes.each do |surfaceType| unless OpenStudio::Model::Surface::validSurfaceTypeValues.include?(surfaceType) raise("ERROR: Invalid surface type = #{surfaceType} Correct Values are: #{OpenStudio::Model::Surface::validSurfaceTypeValues}") end end return_array = Array.new() if surfaceTypes.size == 0 or surfaceTypes[0].upcase == "All".upcase return_array = self else surfaces.each do |surface| surfaceTypes.each do |surfaceType| if surface.surfaceType == surfaceType return_array.push(surface) end end end end return return_array end |
.filter_subsurfaces_by_types(subsurfaces, subSurfaceTypes) ⇒ Object
- “FixedWindow” , “OperableWindow” , “Door” , “GlassDoor”, “OverheadDoor” , “Skylight”, “TubularDaylightDiffuser”,“TubularDaylightDome”
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 595 def self.filter_subsurfaces_by_types(subsurfaces, subSurfaceTypes) #check to see if a string or an array was passed. if subSurfaceTypes.kind_of?(String) temp = subSurfaceTypes subSurfaceTypes = Array.new() subSurfaceTypes.push(temp) end subSurfaceTypes.each do |subSurfaceType| unless OpenStudio::Model::SubSurface::validSubSurfaceTypeValues.include?(subSurfaceType) raise("ERROR: Invalid surface type = #{subSurfaceType} Correct Values are: #{OpenStudio::Model::SubSurface::validSubSurfaceTypeValues}") end end return_array = Array.new() if subSurfaceTypes.size == 0 or subSurfaceTypes[0].upcase == "All".upcase return_array = self else subsurfaces.each do |subsurface| subSurfaceTypes.each do |subSurfaceType| if subsurface.subSurfaceType == subSurfaceType return_array.push(subsurface) end end end end return return_array end |
.get_overlapping_segments(overlap_segs:, index:, point_a1:, point_a2:) ⇒ Object
This method takes the y projections of a bunch of overlapping line segments and sorts them to determines which are unique and, if they are not unique, which is closest to the current, upwardly pointing, line. If several overlapping segments belong to the same line they are put together (after the ‘subdivide_overlaps’ method broke them apart). The end result is the method returns the closet point downward pointing line segments closest to the given upward pointing line segment.
overlap_segs: This is an array of hashes that looks like:
overlap_seg = {
index_a1: i,
index_a2: i-1,
index_b1: j,
index_b2: j-1,
point_b1: surf_verts[j],
point_b2: surf_verts[j-1],
overlap_y: overlap_y
}
index_a1: The index of the array of points that cooresponds with the top of line a (points up) index_a1: The index of the array of points that cooresponds with the bottom of line a (points up) index_b1: The index of the array of points that cooresponds with the bottom of line b (points down) index_b1: The index of the array of points that cooresponds with the top of line b (points down) point_b1: The coordinates of the bottom of line b point_b2: The coordinates of the top of line b
overlap_y: A hash that contains the coordinates of the top and bottom of the y projection of the overlapping lines (line a and line b)
overlap_y = {
overlap_start: overlap_start,
overlap_end: overlap_end
}
overlap_start: The y coordinate of the top of the overlap overlap_end: The y coordinate of the bottom of the overlap
index: The index of the array of points that cooresponds with the top of of the current upward pointing line.
point_a1: The coordinates of the top of the first line point_a2: The coordinates of the bottom of the first line This naming convention was chosen because this method was originally designed to work with the ‘make_concave_surfaces’ method (see above). That method choses lines that point up and then sees where they overlap with lines pointing down. The point_1 of each line is the end of the line. In this case a lines point up and b lines point down.
987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 987 def self.get_overlapping_segments(overlap_segs:, index:, point_a1:, point_a2:) closest_overlaps = [] linea_overlaps = [] # This goes through all the line segments and determines which correspond to the current upward pointing line # segment(line a). It also determines the x coordinate distance between the top and bottom of the overlapping # portions of the line segments. curr_overlap_segs = overlap_segs.select { |seg| (seg[:index_a1] == index) && (seg[:index_a2] == (index - 1)) } curr_overlap_segs.each do |overlap_seg| line_a_x_top = line_segment_overlap_x_coord(y_check: overlap_seg[:overlap_y][:overlap_start], point_b1: point_a1, point_b2: point_a2) line_a_x_bottom = line_segment_overlap_x_coord(y_check: overlap_seg[:overlap_y][:overlap_end], point_b1: point_a1, point_b2: point_a2) line_b_x_top = line_segment_overlap_x_coord(y_check: overlap_seg[:overlap_y][:overlap_start], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2]) line_b_x_bottom = line_segment_overlap_x_coord(y_check: overlap_seg[:overlap_y][:overlap_end], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2]) x_distance_top = line_a_x_top - line_b_x_top x_distance_bottom = line_a_x_bottom - line_b_x_bottom linea_overlap = { dx_top: x_distance_top, dx_bottom: x_distance_bottom, overlap: overlap_seg } linea_overlaps << linea_overlap end # This sorts through the overlapping downward pointing line segments corresponding to the current upward pointing # line a. The overlapping downward pointing line segments closest to the current upward pointing line segment # are kept. The other are discarded. Unique overlapping line segments are kept as well. There should only be # unuique overlapping line segments or overlapping line segments that precisely match one another because of # the 'subdivide_overlaps' method which this method is supposed to work with. linea_overlaps.each do |line_a_overlap| overlaps = linea_overlaps.select { |seg| seg[:overlap][:overlap_y] == line_a_overlap[:overlap][:overlap_y]} if overlaps.size > 1 redundant_overlap = closest_overlaps.select { |dup_seg| dup_seg[:overlap_y] == overlaps[0][:overlap][:overlap_y] } closest_overlaps << (overlaps.min_by { |dup_seg| dup_seg[:dx_top] })[:overlap] if redundant_overlap.empty? elsif overlaps.size == 1 closest_overlaps << overlaps[0][:overlap] end end # This combines the line segments that belong together. These were broken apart because of the # 'subdivide_overlaps' method. overlap_exts = [closest_overlaps[0]] for j in 0..(closest_overlaps.length - 1) index = 0 found = false for l in 0..(overlap_exts.length - 1) if overlap_exts[l][:index_b1] == closest_overlaps[j][:index_b1] && overlap_exts[l][:index_b2] == closest_overlaps[j][:index_b2] index = l found = true break end end if found == false overlap_exts << closest_overlaps[j] index = overlap_exts.length - 1 end for k in 0..(closest_overlaps.length - 1) if (closest_overlaps[j][:index_b1] == closest_overlaps[k][:index_b1]) && (closest_overlaps[j][:index_b2] == closest_overlaps[k][:index_b2]) if closest_overlaps[k][:overlap_y][:overlap_start] >= overlap_exts[index][:overlap_y][:overlap_start] overlap_exts[index][:overlap_y][:overlap_start] = closest_overlaps[k][:overlap_y][:overlap_start] end if closest_overlaps[k][:overlap_y][:overlap_end] <= overlap_exts[index][:overlap_y][:overlap_end] overlap_exts[index][:overlap_y][:overlap_end] = closest_overlaps[k][:overlap_y][:overlap_end] end end end end return overlap_exts end |
.getSurfaceAreafromVertices(vertices:) ⇒ Object
This method calculates the surface area of a 2-D polygon from an array of OpenStudio vertices. It ignores any z vertices. This method assumes that the polygon is complete, has no holes, does not cross itself, and that the vertices are provided in counter-clockwise order. This method is used in cases when you want to find the area of something before creating an OpenStudio surface/subsurface.
Input arguments: vetices: Array of openstudio vertices.
Output: Area: Float, area of polygot represented by the vertices.
1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 1557 def self.getSurfaceAreafromVertices(vertices:) area = 0.0 numberVertices = vertices.size # Check that a polygon is actually provided and not just a line or point. Return 0 if the vertices are a line # or point. return 0.0 if numberVertices < 3 # Go through the vertices and get the cross product. This adopted from: # https://web.archive.org/web/20100405070507/http://valis.cs.uiuc.edu/~sariel/research/CG/compgeom/msg00831.html vertices.each_with_index do |vertex, i| j = (i + 1) % numberVertices area += vertex.x.to_f * vertices[j].y.to_f area -= vertex.y.to_f * vertices[j].x.to_f end return area end |
.hide(surfaces) ⇒ Object
763 764 765 766 767 768 769 770 771 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 763 def self.hide(surfaces) surfaces.each do |surface| if drawing_interface = surface.drawing_interface if entity = drawing_interface.entity entity.visible = false end end end end |
.line_segment_overlap_x_coord(y_check:, point_b1:, point_b2:) ⇒ Object
This method determines the x coordinate of where a given y coordinate crosses a given line. y_check: The y coordinate that you want to determine the x coordinate for on a line point_b1: The coordinates of the bottom of the line point_b2: The coordinates of the top of the line
1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 1511 def self.line_segment_overlap_x_coord(y_check:, point_b1:, point_b2:) # If the line is vertical then all x coordinates are the same if point_b1[:x] == point_b2[:x] xcross = point_b2[:x] # If the line is horizontal you cannot find the y intercept elsif (point_b1[:y] == point_b2[:y]) raise("This line is horizontal so no y intercept can be found.") # Otherwise determine the line coefficients and get the intercept else a = (point_b1[:y] - point_b2[:y]) / (point_b1[:x] - point_b2[:x]) b = point_b1[:y] - a * point_b1[:x] xcross = (y_check - b) / a end return xcross end |
.line_segment_overlap_y?(point_a1:, point_a2:, point_b1:, point_b2:) ⇒ Boolean
This method determines if the y component of 2 lines overlap. point_a1: The top of the first line point_a2: The bottom of the first line point_b1: The bottom of the second line point_b2: The top of the second line. This naming convention was chosen because this method was originally designed to work with the ‘make_concave_surfaces’ method (see above). That method choses lines that point up and then sees where they overlap with lines pointing down. The point_1 of each line is the end of the line. In this case a lines point up and b lines point down.
1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 1473 def self.line_segment_overlap_y?(point_a1:, point_a2:, point_b1:, point_b2:) overlap_start = nil overlap_end = nil # If line a overlaps with the bottom of line b do this: if (point_a1 >= point_b1) && (point_a2 <= point_b1) overlap_start = point_a1 overlap_end = point_b1 # This checks if all of line b is overlapped by line a if point_a1 >= point_b2 overlap_start = point_b2 end # If line a overlaps with the top of line b do this: elsif (point_a1 >= point_b2) && (point_a2 <= point_b2) overlap_start = point_b2 overlap_end = point_a2 # This checks if all of line b is overlapped by line a if point_a2 <= point_b1 overlap_end = point_b1 end # This checks if all of line a fits in line b elsif (point_a1 <= point_b2) && (point_a2 >= point_b1) overlap_start = point_a1 overlap_end = point_a2 end # Overlap vectors always point down. Thus overlap_start is the y location of the top of the overlap vector and # overlap_end is the y location of the bottom of the overlap vector. The overlap vector will later be constructed # using point_b1 and point_b2 and checking which overlaps are closest (and not obstructed) by other overlaps. overlap_y = { overlap_start: overlap_start, overlap_end: overlap_end } return overlap_y end |
.make_convex_surfaces(surface:, tol: 12) ⇒ Object
2018-09-27 Chris Kirney This method takes a surface in the x-y plane (z coordinates are ignored) with an upwardly pointing normal and turns it into convex quadrialaterals. If the original surface is already a convex quadrilateral then this method will go to a lot of trouble to return the same thing (only with the coordinates of the points rounded). If the surface is already a concave surface then this method will return it broken into a bunch of quadrilaters (maybe a triangle here and there). Neither of the above are especially useful. However, the point of this method is if you pass this a concave surface it will return convex surfaces that you can then use with other methods that only apply to convex surfaces (such as a method which fits skylights into a roof). Note that surfaces per say are not returned. Rather, an array containing 4 points arranged in counter clockwise order is returned. These points are also in the x-y plane with an upwardly pointing normal. No z coordinate is returned.
The method works by first looking for upward pointing lines. It then looks for cooresponding downward pointing lines. Since all of the surfaces are closed there should always be enough upward and downward pointing lines. Horizontal lines are ignored. It then checks to see which y projections of the upward and downward pointing lines overlap. It then sees which of these overlaping lines overlap. Ultimately you wind up with a whole bunch of overlapping y projections that coorespond with different upward pointing lines. These overlapping y projects are either unique, or they precisely match other overlapping y projections. The point is that, in the case of a convex shape, an upward pointing line may overlap with some lines close, and some far away, with some lines in between. The method then sorts through the overlapping y projections to see which are closest to a given upward pointing line. It keeps the unique ones, and the ones that are closest. The end result should be downward pointing line segments that correspond to an upward pointing line segment with no intervening lines. The last part of the method assembles the quadrilaterals from the remaining downward pointing line segments which correspond with a given upward pointing line segment.
796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 796 def self.make_convex_surfaces(surface:, tol: 12) # Note that points on surfaces are given counterclockwise when looking at the surface from the opposite direction as # the outward normal (i.e. the outward normal is pointing at you). I use point_a1, point_a2, point_b1 and point b2 # lots. For this, point_a refers to vectors pointing up. In this case point_a1 is at the top of the vector and # point_a2 is at the bottom of the vector. Contrarily, point_b refers to vectors pointing down. In this case # point_b1 is at the bottom of the vector and point_b2 is at the top. All of this comes about because I cycle # through the points starting at the 2nd point and and going to the last point. I count vectors as starting from # the last point and going toward the current point. # See following where P1 through P4 are the points. When cycling through a is where you start and b is where you # end. the o is the tip of the outward normal pointing at you. # P2b------------aP1 # a b # | | # | o | # | | # b a # P3a-----------bP4 surf_verts = [] # Get the vertices from the surface, keep the x and y coordinates, and turn the vertices from OpenStudio's # data structure to a differet one which is a little easier to deal with. Also, round them to the given # tolerance. This is done because some numbers that should match don't because of tiny errors. surface.vertices.each do |vert| surf_vert = { x: vert.x.to_f.round(tol), y: vert.y.to_f.round(tol), z: vert.z.to_f } surf_verts << surf_vert end # If the surface is a triangle or less then do nothing and return it. return surf_verts if surf_verts.length <= 3 # Adding the first vertex to the end so that it is accounted for. surf_verts << surf_verts[0] # Following we go through the points, look for upward pointing lines, then look for downward pointing lines to # their left (only to the left because everything goes counter-clockwise). If there is a line find how much the # current upward pointing line overlaps with it in the y direction. overlap_segs = [] new_surfs = [] for i in 1..(surf_verts.length - 1) # Is this line segment pointing up? If no, then ignore it and go to the next line segment. if surf_verts[i][:y] > surf_verts[i - 1][:y] # Go through each line segment for j in 1..(surf_verts.length - 1) # Is the line segment to the left of the current (index i) line segment? If no, then ignore it and go to the next one. # I revised this to check if the start or end of the current (index i) line segment is to the left of the # line segment being checked. #if surf_verts[j][:x] < surf_verts[i][:x] and surf_verts[j - 1][:x] < surf_verts[i - 1][:x] if surf_verts[j][:x] < surf_verts[i][:x] || surf_verts[j - 1][:x] < surf_verts[i - 1][:x] # Is the line segment pointing down? If no, then ignore it and go to the next line segment. if surf_verts[j][:y] < surf_verts[j - 1][:y] # Do the y coordinates of the line segment overlap with the current (index i) line segment? If no # then ignore it and go to the next line segment. overlap_y = line_segment_overlap_y?(point_a1: surf_verts[i][:y], point_a2: surf_verts[i - 1][:y], point_b1: surf_verts[j][:y], point_b2: surf_verts[j - 1][:y]) unless overlap_y[:overlap_start].nil? || overlap_y[:overlap_end].nil? unless overlap_y[:overlap_start] == overlap_y[:overlap_end] overlap_seg = { index_a1: i, index_a2: i - 1, index_b1: j, index_b2: j - 1, point_b1: surf_verts[j], point_b2: surf_verts[j - 1], overlap_y: overlap_y } overlap_segs << overlap_seg end end end end end end end # This part: # 1. Subdivides the overlapping segments found above into either unique overlaps between the upward and downward # pointing lines or overlapping segments that exactly match one another. # 2. Goes through each upward pointing line and finds the closest overlapping downward pointing line segments (if # these downward pointing segments belong together they are re-attached). # 3. Makes quadrilaterals (or triangles as the case may be) out of each upward pointing line and the closest # downward pointing line segment. if overlap_segs.length > 1 # Subdivide the overlapping segments found above into either unique overlaps between the upward and downward # pointing lines or overlapping segments that exactly match one another. overlap_segs = subdivide_overlaps(overlap_segs: overlap_segs) # Remove redundant overlapping segments recheck = true while recheck recheck = false # Go through each overlapping segment and look for duplicate segments overlap_segs.each_with_index do |ind_overlap_seg, seg_index| # Find duplicate overlapping segments redundant_segs = overlap_segs.select { |check_seg| check_seg == ind_overlap_seg} # Remove the first one and then restart the while loop to recompile the seg_index if redundant_segs.size > 1 overlap_segs.delete_at(seg_index) recheck = true end end end for i in 1..(surf_verts.length - 1) # Does the line point up? No then ignore and go on to the next one. if surf_verts[i][:y] > surf_verts[i - 1][:y] # Finds the closest overlapping downward pointing line segments that correspond to this upward pointing # line (if some of these downward pointing segments belong together then re-attached them). closest_overlaps = get_overlapping_segments(overlap_segs: overlap_segs, index: i, point_a1: surf_verts[i], point_a2: surf_verts[i - 1]) closest_overlaps = closest_overlaps.sort_by {|closest_overlap| closest_overlap[:overlap_y][:overlap_start]} # Create the quadrilaterals out of the downward pointing line segments closest to the current upward # pointing line. for j in 0..(closest_overlaps.length - 1) new_surf = [] z_loc = surf_verts[closest_overlaps[j][:index_a1]][:z] y_loc = closest_overlaps[j][:overlap_y][:overlap_start] x_loc = line_segment_overlap_x_coord(y_check: y_loc, point_b1: surf_verts[closest_overlaps[j][:index_a1]], point_b2: surf_verts[closest_overlaps[j][:index_a2]]) new_surf << {x: x_loc.to_f.round(tol), y: y_loc.to_f.round(tol), z: z_loc.to_f.round(tol)} x_loc = line_segment_overlap_x_coord(y_check: y_loc, point_b1: closest_overlaps[j][:point_b1], point_b2: closest_overlaps[j][:point_b2]) z_loc = surf_verts[closest_overlaps[j][:index_b2]][:z] new_surf << {x: x_loc.to_f.round(tol), y: y_loc.to_f.round(tol), z: z_loc.to_f.round(tol)} y_loc = closest_overlaps[j][:overlap_y][:overlap_end] x_loc = line_segment_overlap_x_coord(y_check: y_loc, point_b1: closest_overlaps[j][:point_b1], point_b2: closest_overlaps[j][:point_b2]) z_loc = surf_verts[closest_overlaps[j][:index_b1]][:z] new_surf << {x: x_loc.to_f.round(tol), y: y_loc.to_f.round(tol), z: z_loc.to_f.round(tol)} x_loc = line_segment_overlap_x_coord(y_check: y_loc, point_b1: surf_verts[closest_overlaps[j][:index_a1]], point_b2: surf_verts[closest_overlaps[j][:index_a2]]) z_loc = surf_verts[closest_overlaps[j][:index_a2]][:z] new_surf << {x: x_loc.to_f.round(tol), y: y_loc.to_f.round(tol), z: z_loc.to_f.round(tol)} # Check if this should be a triangle. for k in 0..(new_surf.length - 1) break_now = false for l in 0..(new_surf.length - 1) next if k == l if (new_surf[k][:x] == new_surf[l][:x]) && (new_surf[k][:y] == new_surf[l][:y]) new_surf.delete_at(l) break_now = true break end end if break_now == true break end end new_surfs << new_surf end end end elsif overlap_segs.length == 1 # There is only one overlapping downward line, thus this is a quadrilateral already so just return it. # Remove the last vertex as we had artificially added it at the start. surf_verts.pop new_surfs << surf_verts end return new_surfs end |
.rotate_tilt_translate_surfaces(planar_surfaces, azimuth_degrees, tilt_degrees = 0.0, translation_vector = OpenStudio::Vector3d.new(0.0, 0.0, 0.0)) ⇒ OpenStudio::Model::Model
This method will rotate a surface
567 568 569 570 571 572 573 574 575 576 577 578 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 567 def self.rotate_tilt_translate_surfaces(planar_surfaces, azimuth_degrees, tilt_degrees = 0.0, translation_vector = OpenStudio::Vector3d.new(0.0, 0.0, 0.0)) # Identity matrix for setting space origins azimuth_matrix = OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0, 0, 1), azimuth_degrees * Math::PI / 180) tilt_matrix = OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0, 0, 1), tilt_degrees * Math::PI / 180) translation_matrix = OpenStudio::createTranslation(translation_vector) planar_surfaces.each do |surface| surface.changeTransformation(azimuth_matrix) surface.changeTransformation(tilt_matrix) surface.changeTransformation(translation_matrix) end return planar_surfaces end |
.set_fenestration_to_wall_ratio(surfaces, ratio, offset = 0, height_offset_from_floor = true, floor = "all") ⇒ Object
580 581 582 583 584 585 586 587 588 589 590 591 592 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 580 def self.set_fenestration_to_wall_ratio(surfaces, ratio, offset = 0, height_offset_from_floor = true, floor = "all") surfaces.each do |surface| result = surface.setWindowToWallRatio(ratio, offset, height_offset_from_floor) raise("Unable to set FWR for surface " + surface.name.get.to_s + " . Possible reasons are if the surface is not a wall, if the surface is not rectangular in face coordinates, if requested ratio is too large (window area ~= surface area) or too small (min dimension of window < 1 foot), or if the window clips any remaining sub surfaces. Otherwise, removes all existing windows and adds new window to meet requested ratio.") unless result end return surfaces end |
.set_surfaces_boundary_condition(model, surfaces, boundaryCondition) ⇒ Object
This method sets the boundary condition for a surface and it’s matching surface.
If set to adiabatic, it will remove all subsurfaces since E+ cannot have adiabatic sub surfaces.
640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 640 def self.set_surfaces_boundary_condition(model, surfaces, boundaryCondition) surfaces = BTAP::Common::validate_array(model, surfaces, "Surface") if OpenStudio::Model::Surface::validOutsideBoundaryConditionValues.include?(boundaryCondition) surfaces.each do |surface| if boundaryCondition == "Adiabatic" #need to remove subsurface as you cannot have a adiabatic surface with a #subsurface. surface.subSurfaces.each do |subsurface| subsurface.remove end #A bug with adiabatic surfaces. They do not hold the default contruction. surface.setConstruction(surface.construction.get()) if surface.isConstructionDefaulted end surface.setOutsideBoundaryCondition(boundaryCondition) adj_surface = surface.adjacentSurface unless adj_surface.empty? adj_surface.get.setOutsideBoundaryCondition(boundaryCondition) end end else puts "ERROR: Invalid Boundary Condition = " + boundary_condition puts "Correct Values are:" puts OpenStudio::Model::Surface::validOutsideBoundaryConditionValues end end |
.set_surfaces_construction_conductance(surfaces, conductance) ⇒ Object
This method creates a new construction based on the current, changes the rsi and assign the construction to the current surface. Most of the meat of this method is in the construction class. Testing is done there.
626 627 628 629 630 631 632 633 634 635 636 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 626 def self.set_surfaces_construction_conductance(surfaces, conductance) surfaces.each do |surface| #a bit of acrobatics to get the construction object from the ConstrustionBase object's name. construction = OpenStudio::Model::getConstructionByName(surface.model, surface.construction.get.name.to_s).get #create a new construction with the requested conductance value based on the current construction. new_construction = BTAP::Resources::Envelope::Constructions::customize_opaque_construction(surface.model, construction, conductance) surface.setConstruction(new_construction) end return surfaces end |
.show(surfaces) ⇒ Object
753 754 755 756 757 758 759 760 761 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 753 def self.show(surfaces) surfaces.each do |surface| if drawing_interface = surface.drawing_interface if entity = drawing_interface.entity entity.visible = false end end end end |
.subdivide_overlaps(overlap_segs:) ⇒ Object
This method was originally written to work with the ‘make_concave_surfaces’ method above. It takes the y-components of a bunch of line segemnts and cuts them up until they either are unique (no other overlapping components) or they match the y-components of other line segments. overlap_segs: This is an array of hashes that looks like:
overlap_seg = {
index_a1: i,
index_a2: i-1,
index_b1: j,
index_b2: j-1,
point_b1: surf_verts[j],
point_b2: surf_verts[j-1],
overlap_y: overlap_y
}
index_a1: The index of the array of points that cooresponds with the top of line a (points up) index_a1: The index of the array of points that cooresponds with the bottom of line a (points up) index_b1: The index of the array of points that cooresponds with the bottom of line b (points down) index_b1: The index of the array of points that cooresponds with the top of line b (points down) point_b1: The coordinates of the bottom of line b point_b2: The coordinates of the top of line b
overlap_y: A hash that contains the coordinates of the top and bottom of the y projection of the overlapping lines (line a and line b)
overlap_y = {
overlap_start: overlap_start,
overlap_end: overlap_end
}
overlap_start: The y coordinate of the top of the overlap overlap_end: The y coordinate of the bottom of the overlap
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 1083 def self.subdivide_overlaps(overlap_segs:) restart = true # Keep doing this until the y projections of the lines are either unique or the match the y projections of other # lines. while restart == true restart = false overlap_segs.each_with_index do |overlap_seg, curr_seg_index| for j in 0..(overlap_segs.length - 1) # Skip this y projection if it is the same as that in overlap_seg if overlap_seg == overlap_segs[j] next end # Check to see if the y projection of line a overlaps with the y projection of line b overlap_segs_overlap = line_segment_overlap_y?(point_a1: overlap_seg[:overlap_y][:overlap_start], point_a2: overlap_seg[:overlap_y][:overlap_end], point_b1: overlap_segs[j][:overlap_y][:overlap_end], point_b2: overlap_segs[j][:overlap_y][:overlap_start]) # If the y projections of the two lines overlap then the components of overlap_segs_overlap should not be # nil. unless ((overlap_segs_overlap[:overlap_start].nil?) || (overlap_segs_overlap[:overlap_end].nil?)) # If the two overlaping segments start and end at the same point then do nothing and go to the next segment. if (overlap_seg[:overlap_y][:overlap_start] == overlap_segs[j][:overlap_y][:overlap_start]) && (overlap_seg[:overlap_y][:overlap_end] == overlap_segs[j][:overlap_y][:overlap_end]) next # If the start point of one overlapping segment shares the end point of the other overlapping segment then # they are not really overlapping. Ignore and go to the next point. elsif overlap_segs_overlap[:overlap_start] == overlap_segs_overlap[:overlap_end] next # If the overlap_seg segment covers beyond the overlap_segs[j] segment then break overlap_seg into three smaller pieces: # -One piece for where overlap_seg starts to where overlap_segs[j] starts; # -One piece to cover overlap_segs[j] (the middle part); and # -One piece for where overlap_segs[j] ends to where overlap_seg ends (the bottom part). # The overlap_segs[j] remains as it is associated with another upward pointing line segment. # If overlap_seg starts at the same point as overlap_segs[j] or ends at the same point as overlap_segs[j] # then overlap_seg is broken into two pieces (no mid piece). elsif (overlap_seg[:overlap_y][:overlap_start] >= overlap_segs[j][:overlap_y][:overlap_start]) && (overlap_seg[:overlap_y][:overlap_end] <= overlap_segs[j][:overlap_y][:overlap_end]) # If the overlap_seg and overlap_segs[j] start at the same point replace overlap_seg with two segments ( # one top and one bottom). if overlap_seg[:overlap_y][:overlap_start] == overlap_segs[j][:overlap_y][:overlap_start] overlap_top = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_seg[:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(curr_seg_index) overlap_segs << overlap_top overlap_segs << overlap_bottom elsif overlap_seg[:overlap_y][:overlap_end] == overlap_segs[j][:overlap_y][:overlap_end] # If the overlap_seg and overlap_segs[j] end at the same point replace overlap_seg with two segments ( # one top and one bottom). overlap_top_over = { overlap_start: overlap_seg[:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_top_over } overlap_bottom = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_segs_overlap } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(curr_seg_index) overlap_segs << overlap_top overlap_segs << overlap_bottom elsif (overlap_seg[:overlap_y][:overlap_start] > overlap_segs[j][:overlap_y][:overlap_start]) && (overlap_seg[:overlap_y][:overlap_end] < overlap_segs[j][:overlap_y][:overlap_end]) # If the overlap_seg stretches above and below overlap_segs[j] then break overlap_seg into three pieces # (one top, one middle, one bottom). overlap_top_over = { overlap_start: overlap_seg[:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_top_over } overlap_mid = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_seg[:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(curr_seg_index) overlap_segs << overlap_top overlap_segs << overlap_mid overlap_segs << overlap_bottom end restart = true break # If the overlap_segs[j] segment covers beyond the overlap_seg segment then break overlap_segs[j] into three smaller pieces: # -One piece for where overlap_segs[j] starts to where overlap_seg starts; # -One piece to cover overlap_seg (the middle part); and # -One piece for where overlap_seg ends to where overlap_segs[j] ends (the bottom part). # The overlap_seg remains as it is associated with another upward pointing line segment. # If overlap_segs[j] starts at the same point as overlap_seg or ends at the same point as overlap_seg # then overlap_segs[j] is broken into two pieces (no mid piece). elsif overlap_seg[:overlap_y][:overlap_start] <= overlap_segs[j][:overlap_y][:overlap_start] && overlap_seg[:overlap_y][:overlap_end] >= overlap_segs[j][:overlap_y][:overlap_end] # If the overlap_seg and overlap_segs[j] start at the same point replace overlap_segs[j] with two segments ( # one top and one bottom). if overlap_seg[:overlap_y][:overlap_start] == overlap_segs[j][:overlap_y][:overlap_start] overlap_top = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_segs[j][:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(j) overlap_segs << overlap_top overlap_segs << overlap_bottom elsif overlap_seg[:overlap_y][:overlap_end] == overlap_segs[j][:overlap_y][:overlap_end] # If the overlap_seg and overlap_segs[j] end at the same point replace overlap_segs[j] with two segments ( # one top and one bottom). overlap_top_over = { overlap_start: overlap_segs[j][:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_top_over } overlap_bottom = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_segs_overlap } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(j) overlap_segs << overlap_top overlap_segs << overlap_bottom elsif overlap_seg[:overlap_y][:overlap_start] < overlap_segs[j][:overlap_y][:overlap_start] && overlap_seg[:overlap_y][:overlap_end] > overlap_segs[j][:overlap_y][:overlap_end] # If the overlap_segs[j] stretches above and below overlap_seg then break overlap_segs[j] into three pieces # (one top, one middle, one bottom). overlap_top_over = { overlap_start: overlap_segs[j][:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_top_over } overlap_mid = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_segs[j][:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. overlap_segs.delete_at(j) overlap_segs << overlap_top overlap_segs << overlap_mid overlap_segs << overlap_bottom end restart = true break # if overlap_seg covers the top of overlap_segs[j] then break overlap_seg into a top and an overlap portion # ond break overlap_segs[j] into an overlap portion and a bottom portion. elsif (overlap_seg[:overlap_y][:overlap_start] >= overlap_segs[j][:overlap_y][:overlap_start]) && (overlap_seg[:overlap_y][:overlap_end] <= overlap_segs[j][:overlap_y][:overlap_start]) && (overlap_seg[:overlap_y][:overlap_end] > overlap_segs[j][:overlap_y][:overlap_end]) overlap_top_over = { overlap_start: overlap_seg[:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_top_over } overlap_mid_seg = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_segs_overlap } overlap_mid_segs = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_segs[j][:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. if curr_seg_index > j overlap_segs.delete_at(curr_seg_index) overlap_segs.delete_at(j) else overlap_segs.delete_at(j) overlap_segs.delete_at(curr_seg_index) end overlap_segs << overlap_top overlap_segs << overlap_mid_seg overlap_segs << overlap_mid_segs overlap_segs << overlap_bottom restart = true break elsif (overlap_seg[:overlap_y][:overlap_start] >= overlap_segs[j][:overlap_y][:overlap_end]) && (overlap_seg[:overlap_end] < overlap_segs[j][:overlap_end]) && (overlap_seg[:overlap_y][:overlap_start] <= overlap_segs[j][:overlap_y][:overlap_start]) # if overlap_seg covers the bottom of overlap_segs[j] then break overlap_segs[j] into a top and an overlap portion # ond break overlap_seg into an overlap portion and a bottom portion. overlap_top_over = { overlap_start: overlap_segs[j][:overlap_y][:overlap_start], overlap_end: overlap_segs_overlap[:overlap_start] } overlap_top = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_top_over } overlap_mid_seg = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_segs_overlap } overlap_mid_segs = { index_a1: overlap_segs[j][:index_a1], index_a2: overlap_segs[j][:index_a2], index_b1: overlap_segs[j][:index_b1], index_b2: overlap_segs[j][:index_b2], point_b1: overlap_segs[j][:point_b1], point_b2: overlap_segs[j][:point_b2], overlap_y: overlap_segs_overlap } overlap_bottom_over = { overlap_start: overlap_segs_overlap[:overlap_end], overlap_end: overlap_seg[:overlap_y][:overlap_end] } overlap_bottom = { index_a1: overlap_seg[:index_a1], index_a2: overlap_seg[:index_a2], index_b1: overlap_seg[:index_b1], index_b2: overlap_seg[:index_b2], point_b1: overlap_seg[:point_b1], point_b2: overlap_seg[:point_b2], overlap_y: overlap_bottom_over } # delete the existing y projection overlaps and replace it with the ones we just made. if curr_seg_index > j overlap_segs.delete_at(curr_seg_index) overlap_segs.delete_at(j) else overlap_segs.delete_at(j) overlap_segs.delete_at(curr_seg_index) end overlap_segs << overlap_top overlap_segs << overlap_mid_seg overlap_segs << overlap_mid_segs overlap_segs << overlap_bottom restart = true break end end end if restart == true break end end end return overlap_segs end |
.surf_centroid(surf:) ⇒ Object
This method finds the centroid of a surface using the point averaging method. OpenStudio already has something which does this but you have to turn something into a special OpenStudio surface first which you may not want to do.
1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 |
# File 'lib/openstudio-standards/btap/geometry.rb', line 1530 def self.surf_centroid(surf:) new_surf_cent = { x: 0, y: 0, z: 0 } surf.each do |surf_vert| new_surf_cent[:x] += surf_vert[:x] new_surf_cent[:y] += surf_vert[:y] new_surf_cent[:z] += surf_vert[:z] end new_surf_cent[:x] /= surf.length new_surf_cent[:y] /= surf.length new_surf_cent[:z] /= surf.length return new_surf_cent end |