示例#1
0
def test_intersect_line_ray():
    """Test the Polyface3D intersect_line_ray method."""
    pts = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 1, 2),
           Point3D(1, 1, 2), Point3D(1, 2, 2), Point3D(0, 2, 2))
    plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2))
    face = Face3D(pts, plane)
    polyface = Polyface3D.from_offset_face(face, 1)
    ray_1 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))
    ray_2 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, -1))
    ray_3 = Ray3D(Point3D(1.5, 1.5, 0), Vector3D(0, 0, 1))
    ray_4 = Ray3D(Point3D(-1, -1, 0), Vector3D(0, 0, 1))
    line_1 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 3))
    line_2 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))

    assert polyface.does_intersect_line_ray_exist(ray_1) is True
    assert polyface.does_intersect_line_ray_exist(ray_2) is False
    assert polyface.does_intersect_line_ray_exist(ray_3) is False
    assert polyface.does_intersect_line_ray_exist(ray_4) is False
    assert polyface.does_intersect_line_ray_exist(line_1) is True
    assert polyface.does_intersect_line_ray_exist(line_2) is False

    assert polyface.intersect_line_ray(ray_1) == [
        Point3D(0.5, 0.5, 2), Point3D(0.5, 0.5, 3)
    ]
    assert polyface.intersect_line_ray(ray_2) == []
    assert polyface.intersect_line_ray(ray_3) == []
    assert polyface.intersect_line_ray(ray_4) == []
    assert polyface.intersect_line_ray(line_1) == [
        Point3D(0.5, 0.5, 2), Point3D(0.5, 0.5, 3)
    ]
    assert polyface.intersect_line_ray(line_2) == []
示例#2
0
def test_ray3_to_from_dict():
    """Test the to/from dict of Ray3D objects."""
    pt = Point3D(2, 0, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)
    ray_dict = ray.to_dict()
    new_ray = Ray3D.from_dict(ray_dict)
    assert isinstance(new_ray, Ray3D)
    assert new_ray.to_dict() == ray_dict
示例#3
0
def test_reflect():
    """Test the Ray3D reflect method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    origin_1 = Point3D(0, 1, 2)
    origin_2 = Point3D(1, 1, 2)
    normal_1 = Vector3D(0, 1, 0)
    normal_2 = Vector3D(-1, 1, 0).normalize()

    assert ray.reflect(normal_1, origin_1).p == Point3D(2, 0, 2)
    assert ray.reflect(normal_1, origin_1).v == Vector3D(0, -2, 0)
    assert ray.reflect(normal_1, origin_2).p == Point3D(2, 0, 2)
    assert ray.reflect(normal_1, origin_2).v == Vector3D(0, -2, 0)

    test_1 = ray.reflect(normal_2, origin_2)
    assert test_1.p == Point3D(2, 2, 2)
    assert test_1.v.x == pytest.approx(2, rel=1e-3)
    assert test_1.v.y == pytest.approx(0, rel=1e-3)
    assert test_1.v.z == pytest.approx(0, rel=1e-3)

    test_2 = ray.reflect(normal_2, origin_1)
    assert test_2.p.x == pytest.approx(1, rel=1e-3)
    assert test_2.p.y == pytest.approx(3, rel=1e-3)
    assert test_2.p.z == pytest.approx(2, rel=1e-3)
    assert test_2.v.x == pytest.approx(2, rel=1e-3)
    assert test_2.v.y == pytest.approx(0, rel=1e-3)
    assert test_2.v.z == pytest.approx(0, rel=1e-3)
示例#4
0
def test_intersect_line_ray():
    """Test the Plane intersect_line_ray method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    plane = Plane(vec, pt)

    test_seg = LineSegment3D(Point3D(0, 4, 0), Vector3D(1, 1, 1))
    assert plane.intersect_line_ray(test_seg) is None

    test_seg = LineSegment3D(Point3D(0, 0, 0), Vector3D(3, 3, 3))
    assert plane.intersect_line_ray(test_seg) == Point3D(2, 2, 2)

    test_ray = Ray3D(Point3D(0, 4, 0), Vector3D(1, 1, 1))
    assert plane.intersect_line_ray(test_ray) is None

    test_ray = Ray3D(Point3D(0, 4, 0), Vector3D(-1, -1, -1))
    assert plane.intersect_line_ray(test_ray) == Point3D(-2, 2, -2)
示例#5
0
def test_intersect_plane():
    """Test the Plane intersect_plane method."""
    pt_1 = Point3D(2, 2, 2)
    vec_1 = Vector3D(0, 2, 0)
    plane_1 = Plane(vec_1, pt_1)
    pt_2 = Point3D(0, 0, 0)
    vec_2 = Vector3D(2, 0, 0)
    plane_2 = Plane(vec_2, pt_2)
    pt_3 = Point3D(0, 0, 0)
    vec_3 = Vector3D(0, 2, 0)
    plane_3 = Plane(vec_3, pt_3)

    assert plane_1.intersect_plane(plane_2) == Ray3D(
        Point3D(0, 2, 0), Vector3D(0, 0, -1))
    assert plane_1.intersect_plane(plane_3) is None
    assert plane_2.intersect_plane(plane_3) == Ray3D(
        Point3D(0, 0, 0), Vector3D(0, 0, 1))
示例#6
0
def test_scale_world_origin():
    """Test the Ray3D scale method with None origin."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    new_ray = ray.scale(2)
    assert new_ray.p == Point3D(4, 4, 4)
    assert new_ray.v == Point3D(0, 4)
    assert new_ray.v.magnitude == 4
示例#7
0
def test_intersect_line_ray():
    """Test the Face3D intersect_line_ray method."""
    pts = (Point3D(0, 0, 2), Point3D(2, 0, 2), Point3D(2, 1, 2),
           Point3D(1, 1, 2), Point3D(1, 2, 2), Point3D(0, 2, 2))
    plane = Plane(Vector3D(0, 0, 1), Point3D(0, 0, 2))
    face = Face3D(pts, plane)
    ray_1 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))
    ray_2 = Ray3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, -1))
    ray_3 = Ray3D(Point3D(1.5, 1.5, 0), Vector3D(0, 0, 1))
    ray_4 = Ray3D(Point3D(-1, -1, 0), Vector3D(0, 0, 1))
    line_1 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 3))
    line_2 = LineSegment3D(Point3D(0.5, 0.5, 0), Vector3D(0, 0, 1))

    assert face.intersect_line_ray(ray_1) == Point3D(0.5, 0.5, 2)
    assert face.intersect_line_ray(ray_2) is None
    assert face.intersect_line_ray(ray_3) is None
    assert face.intersect_line_ray(ray_4) is None
    assert face.intersect_line_ray(line_1) == Point3D(0.5, 0.5, 2)
    assert face.intersect_line_ray(line_2) is None
示例#8
0
def test_move():
    """Test the Ray3D move method."""
    pt = Point3D(2, 0, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    vec_1 = Vector3D(2, 2, 2)
    new_ray = ray.move(vec_1)
    assert new_ray.p == Point3D(4, 2, 4)
    assert new_ray.v == vec
    assert new_ray.v.magnitude == 2
示例#9
0
def test_distance_to_point():
    """Test the Ray3D distance_to_point method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    near_pt = Point3D(3, 3, 2)
    assert ray.distance_to_point(near_pt) == 1
    near_pt = Point3D(2, 0, 2)
    assert ray.distance_to_point(near_pt) == 2
    near_pt = Point3D(1, 5, 2)
    assert ray.distance_to_point(near_pt) == 1
示例#10
0
def test_closest_point():
    """Test the Ray3D closest_point method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    near_pt = Point3D(3, 3, 0)
    assert ray.closest_point(near_pt) == Point3D(2, 3, 2)
    near_pt = Point3D(2, 0, 0)
    assert ray.closest_point(near_pt) == Point3D(2, 2, 2)
    near_pt = Point3D(1, 5, 0)
    assert ray.closest_point(near_pt) == Point3D(2, 5, 2)
示例#11
0
def test_ray3d_init():
    """Test the initalization of Ray3D objects and basic properties."""
    pt = Point3D(2, 0, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)
    str(ray)  # test the string representation of the ray

    assert ray.p == Point3D(2, 0, 2)
    assert ray.v == Vector3D(0, 2, 0)

    flip_ray = ray.reverse()
    assert flip_ray.p == Point3D(2, 0, 2)
    assert flip_ray.v == Vector3D(0, -2, 0)
示例#12
0
def test_scale():
    """Test the Ray3D scale method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    origin_1 = Point3D(0, 2, 2)
    origin_2 = Point3D(1, 1, 2)
    new_ray = ray.scale(2, origin_1)
    assert new_ray.p == Point3D(4, 2, 2)
    assert new_ray.v == Point3D(0, 4, 0)
    assert new_ray.v.magnitude == 4

    new_ray = ray.scale(2, origin_2)
    assert new_ray.p == Point3D(3, 3, 2)
    assert new_ray.v == Point3D(0, 4, 0)
示例#13
0
def test_rotate_xy():
    """Test the Ray3D rotate_xy method."""
    pt = Point3D(2, 2, 2)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)
    origin_1 = Point3D(0, 2, 2)

    test_1 = ray.rotate_xy(math.pi, origin_1)
    assert test_1.p.x == pytest.approx(-2, rel=1e-3)
    assert test_1.p.y == pytest.approx(2, rel=1e-3)
    assert test_1.v.x == pytest.approx(0, rel=1e-3)
    assert test_1.v.y == pytest.approx(-2, rel=1e-3)

    test_2 = ray.rotate_xy(math.pi / 2, origin_1)
    assert test_2.p.x == pytest.approx(0, rel=1e-3)
    assert test_2.p.y == pytest.approx(4, rel=1e-3)
    assert test_2.v.x == pytest.approx(-2, rel=1e-3)
    assert test_2.v.y == pytest.approx(0, rel=1e-3)
示例#14
0
def test_linerayment2_mutability():
    """Test the immutability of Ray3D objects."""
    pt = Point3D(2, 0, 0)
    vec = Vector3D(0, 2, 0)
    ray = Ray3D(pt, vec)

    assert isinstance(ray, Ray3D)
    with pytest.raises(AttributeError):
        ray.p.x = 3
    with pytest.raises(AttributeError):
        ray.v.x = 3
    with pytest.raises(AttributeError):
        ray.p = Point3D(0, 0, 0)
    with pytest.raises(AttributeError):
        ray.v = Vector3D(2, 2, 0)

    ray_copy = ray.duplicate()
    assert ray.p == ray_copy.p
    assert ray.v == ray_copy.v
示例#15
0
    def ground_by_custom_surface(self,
                                 ground_geometry,
                                 tolerance=0.01,
                                 angle_tolerance=1.0):
        """Set ground boundary conditions using an array of Face3D for the ground.

        Room faces that are coplanar with the ground surface or lie completely below it
        will get a Ground boundary condition while those above will get an Outdoors
        boundary condition. Existing Faces with an indoor boundary condition will
        be unaffected.

        Args:
            ground_geometry: An array of ladybug_geometry Face3D that together
                represent the ground surface.
            tolerance: The minimum difference between the coordinate values of two
                vertices at which they can be considered equivalent. Default: 0.01,
                suitable for objects in meters.
            angle_tolerance: The max angle in degrees that the plane normals can
                differ from one another in order for them to be considered
                coplanar. (Default: 1)
        """
        # default values used throughout the check
        ang_tol = math.degrees(angle_tolerance)
        up_vec = Vector3D(0, 0, 1)

        # loop through the faces and check their relation to the ground geometry
        for face in self.faces:
            if isinstance(face.boundary_condition, (Outdoors, Ground)):
                ray = Ray3D(face.center, up_vec)
                for grnd_geo in ground_geometry:
                    # first check if the surface is below the ground surface
                    if grnd_geo.intersect_line_ray(ray):
                        face.boundary_condition = boundary_conditions.ground
                        break
                    # then check if the Face is coplanar with the ground face
                    pl1, pl2 = face.geometry.plane, grnd_geo.plane
                    if pl1.is_coplanar_tolerance(pl2, tolerance, ang_tol):
                        if grnd_geo.is_point_on_face(face.center, tolerance):
                            face.boundary_condition = boundary_conditions.ground
                            break
                else:
                    face.boundary_condition = boundary_conditions.outdoors
示例#16
0
    def set_top_exposed_by_story_above(self, story_above, tolerance=0.01):
        """Set the child Room2Ds of this object to have ceilings exposed to the outdoors.

        Args:
            story_above: A Story object that sits above this Story. Each Room2D
                of this Story will be checked to see if it intersects the Story
                above and the top exposure will be set based on this.
            tolerance: The minimum difference between the coordinate values of two
                faces at which they can be considered adjacent. Default: 0.01,
                suitable for objects in meters.
        """
        up_vec = Vector3D(0, 0, 1)
        for room in self._room_2ds:
            face_ray = Ray3D(room._floor_geometry._point_on_face(tolerance), up_vec)
            for other_room in story_above._room_2ds:
                if other_room._floor_geometry.intersect_line_ray(face_ray) is not None:
                    room.is_top_exposed = False
                    break
            else:
                room.is_top_exposed = True
示例#17
0
    # convert all of the _source_geo and contex into a single Brep for ray tracing
    rtrace_brep = join_geometry_to_brep(_source_geo + context_)

    # autocompute the first and last bounce length if it's unspecified
    if _first_length_ is None or _last_length_ is None:
        max_pt, min_pt = (to_point3d(p)
                          for p in bounding_box_extents(rtrace_brep))
        diag_dist = max_pt.distance_to_point(min_pt)
        _first_length_ = diag_dist if _first_length_ is None else _first_length_
        _last_length_ = diag_dist if _last_length_ is None else _last_length_

    # create the gridded mesh from the _source_geo and set up the starting rays
    study_mesh = to_joined_gridded_mesh3d(_source_geo, _grid_size)
    move_vec = neg_lb_vec * _first_length_
    source_points = [pt + move_vec for pt in study_mesh.face_centroids]
    lb_rays = [Ray3D(pt, lb_vec) for pt in source_points]
    start_rays = [from_ray3d(ray) for ray in lb_rays]

    # trace each ray through the geometry
    cutoff_ang = math.pi / 2
    rtrace_geo = [rtrace_brep]
    rays, int_pts = [], []
    for ray, pt, norm in zip(start_rays, source_points,
                             study_mesh.face_normals):
        if norm.angle(neg_lb_vec) < cutoff_ang:
            pl_pts = trace_ray(ray, rtrace_geo, _bounce_count_ + 1)
            # if the intersection was successful, create a polyline represeting the ray
            if pl_pts:
                # gather all of the intersection points
                all_pts = [pt]
                for i_pt in pl_pts:
示例#18
0
def to_ray3d(ray):
    """Ladybug Ray3D from Rhino Ray3d."""
    return Ray3D(to_point3d(ray.Position), to_vector3d(ray.Direction))