module URBANopt::GeoJSON::Zoning

Public Class Methods

divide_floor_print(floor_print, perimeter_depth, runner, scale = false) click to toggle source

This method divides the floor print using perimeter and core zoning at the depth of the perimeter_depth.

It returns an Array of Arrays containing instances of OpenStudio::Point3d .

Parameters
  • floor_print - Type:Array - An instance of OpenStudio::Point3dVector.new .

  • perimeter_depth - Type:Float - Represents perimeter depth.

  • runner - Type:String - Measure run's instance of OpenStudio::Measure::OSRunner .

  • scale - Type:Boolean - Checks whether floor print is to be scaled. Default is false.

# File lib/urbanopt/geojson/zoning.rb, line 20
def self.divide_floor_print(floor_print, perimeter_depth, runner, scale = false)
  result = []
  t_inv = OpenStudio::Transformation.alignFace(floor_print)
  t = t_inv.inverse
  vertices = t * floor_print
  new_vertices = OpenStudio::Point3dVector.new
  n = vertices.size
  (0...n).each do |i|
    vertex_1 = nil
    vertex_2 = nil
    vertex_3 = nil
    if i == 0
      vertex_1 = vertices[n - 1]
      vertex_2 = vertices[i]
      vertex_3 = vertices[i + 1]
    elsif i == (n - 1)
      vertex_1 = vertices[i - 1]
      vertex_2 = vertices[i]
      vertex_3 = vertices[0]
    else
      vertex_1 = vertices[i - 1]
      vertex_2 = vertices[i]
      vertex_3 = vertices[i + 1]
    end
    vector_1 = (vertex_2 - vertex_1)
    vector_2 = (vertex_3 - vertex_2)
    angle_1 = Math.atan2(vector_1.y, vector_1.x) + Math::PI / 2.0
    angle_2 = Math.atan2(vector_2.y, vector_2.x) + Math::PI / 2.0
    vector = OpenStudio::Vector3d.new(Math.cos(angle_1) + Math.cos(angle_2), Math.sin(angle_1) + Math.sin(angle_2), 0)
    vector.setLength(perimeter_depth)
    new_point = vertices[i] + vector
    new_vertices << new_point
  end
  normal = OpenStudio.getOutwardNormal(new_vertices)
  if normal.empty? || normal.get.z < 0
    runner.registerWarning('Wrong direction for resulting normal, will not divide')
    return [floor_print]
  end
  self_intersects = OpenStudio.selfIntersects(OpenStudio.reverse(new_vertices), 0.01)
  if OpenStudio::VersionString.new(OpenStudio.openStudioVersion) < OpenStudio::VersionString.new('1.12.4')
    self_intersects = !self_intersects
  end
  if self_intersects
    runner.registerWarning('Self intersecting surface result, will not divide')
  end
  if scale == true
    result = t_inv * new_vertices
  else
    result << t_inv * new_vertices
    (0...n).each do |i|
      perim_vertices = OpenStudio::Point3dVector.new
      if i == (n - 1)
        perim_vertices << vertices[i]
        perim_vertices << vertices[0]
        perim_vertices << new_vertices[0]
        perim_vertices << new_vertices[i]
      else
        perim_vertices << vertices[i]
        perim_vertices << vertices[i + 1]
        perim_vertices << new_vertices[i + 1]
        perim_vertices << new_vertices[i]
      end
      result << t_inv * perim_vertices
    end
  end
  return result
end
get_first_floor_points(multi_polygons, origin_lat_lon, runner) click to toggle source

The get_first_floor_points is used to return the points for the first floor.

It returns an Array containing instances of OpenStudio::Point3d.

Parameters
  • multi_polygons - Type-Array - Coordinate pairs in double nested Array .

  • origin_lat_lon - Type-Float - An instance of OpenStudio::PointLatLon indicating origin latitude and longitude.

  • runner - Type-String - Measure run's instance of OpenStudio::Measure::OSRunner .

# File lib/urbanopt/geojson/zoning.rb, line 98
def self.get_first_floor_points(multi_polygons, origin_lat_lon, runner)
  building_points = []
  multi_polygons.each do |multi_polygon|
    multi_polygon.each do |polygon|
      elevation = 0
      floor_print = URBANopt::GeoJSON::Helper.floor_print_from_polygon(polygon, elevation, origin_lat_lon, runner, true)
      floor_print.each do |point|
        building_points << point
      end
      break
    end
  end
  return building_points
end