Exemplo n.º 1
0
def intersecPerpendicularLine(A, B, C, info=0):
    """ Return the intersection between the Line L defined by A and B
    and the Line perpendicular crossing the point C.
    """
    if A == B:
        return None
    ax, ay, az = A.x, A.y, A.z
    bx, by, bz = B.x, B.y, B.z
    cx, cy, cz = C.x, C.y, C.z
    ux, uy, uz = bx - ax, by - ay, bz - az
    if (ux * ux + uy * uy + uz * uz) == 0.0:
        return None
    k = (ux * cx + uy * cy + uz * cz - ux * ax - uy * ay -
         uz * az) / (ux * ux + uy * uy + uz * uz)
    tx = ax + k * ux
    ty = ay + k * uy
    tz = az + k * uz
    T = Vector(tx, ty, tz)
    vx, vy, vz = tx - cx, ty - cy, tz - cz
    V = Vector(vx, vy, vz)
    distance = math.sqrt(V.dot(V))
    #    Tprime = T + V
    if info == 1:
        msgCsl("Intersection Point at distance of " + str(distance) +
               " is : " + format(T))
    return T  #, distance, Tprime
Exemplo n.º 2
0
def intersecLinePlane(A, B, plane):
    """ Return the intersection between a line A,B and a planar face.
    """
    N = plane.normalAt(0, 0)
    a, b, c = N.x, N.y, N.z
    p1 = plane.CenterOfMass
    d = -((a * p1.x) + (b * p1.y) + (c * p1.z))
    ax, ay, az = A.x, A.y, A.z
    bx, by, bz = B.x, B.y, B.z
    ux, uy, uz = bx - ax, by - ay, bz - az
    U = Vector(ux, uy, uz)

    if U.dot(N) == 0.0:
        # if A belongs to P : the full Line L is included in the Plane
        if (a * ax) + (b * ay) + (c * az) + d == 0.0:
            return A
        # if not the Plane and line are paralell without intersection
        else:
            return None
    else:
        if (a * ux + b * uy + c * uz) == 0.0:
            return None
        k = -1 * (a * ax + b * ay + c * az + d) / (a * ux + b * uy + c * uz)
        tx = ax + k * ux
        ty = ay + k * uy
        tz = az + k * uz
        T = Vector(tx, ty, tz)
        return T
Exemplo n.º 3
0
    def projectPoint(self, p, direction=None, force_projection=True):
        """Project a point onto the plane, by default orthogonally.

        Parameters
        ----------
        p : Base::Vector3
            The point to project.
        direction : Base::Vector3, optional
            The unit vector that indicates the direction of projection.

            It defaults to `None`, which then uses the `plane.axis` (normal)
            value, meaning that the point is projected perpendicularly
            to the plane.
        force_projection: Bool, optional
            Forces the projection if the deviation between the direction and
            the normal is less than float epsilon from the orthogonality.
            The direction of projection is modified to a float epsilon
            deviation between the direction and the orthogonal.
            It defaults to True.

        Returns
        -------
        Base::Vector3
            The projected vector, scaled to the appropriate distance.
        """

        axis = Vector(self.axis).normalize()
        if direction is None:
            dir = axis
        else:
            dir = Vector(direction).normalize()

        cos = dir.dot(axis)
        delta_ax_proj = (p - self.position).dot(axis)
        # check the only conflicting case: direction orthogonal to axis
        if abs(cos) <= float_info.epsilon:
            if force_projection:
                cos = math.copysign(float_info.epsilon, delta_ax_proj)
                dir = axis.cross(dir).cross(axis) - cos * axis
            else:
                return None

        proj = p - delta_ax_proj / cos * dir

        return proj
Exemplo n.º 4
0
def get_spherical_coords(x, y, z):
    """Get the Spherical coordinates of the vector represented
    by Cartesian coordinates (x, y, z).

    Parameters
    ----------
    vector : Base::Vector3
        The input vector.

    Returns
    -------
    tuple of float
        Tuple (radius, theta, phi) with the Spherical coordinates.
        Radius is the radial coordinate, theta the polar angle and
        phi the azimuthal angle in radians.

    Notes
    -----
    The vector (0, 0, 0) has undefined values for theta and phi, while
    points on the z axis has undefined value for phi. The following
    conventions are used (useful in DraftToolBar methods):
    (0, 0, 0) -> (0, pi/2, 0)
    (0, 0, z) -> (radius, theta, 0)
    """

    v = Vector(x, y, z)
    x_axis = Vector(1, 0, 0)
    z_axis = Vector(0, 0, 1)
    y_axis = Vector(0, 1, 0)
    rad = v.Length

    if not bool(round(rad, precision())):
        return (0, math.pi / 2, 0)

    theta = v.getAngle(z_axis)
    v.projectToPlane(Vector(0, 0, 0), z_axis)
    phi = v.getAngle(x_axis)
    if math.isnan(phi):
        return (rad, theta, 0)
    # projected vector is on 3rd or 4th quadrant
    if v.dot(Vector(y_axis)) < 0:
        phi = -1 * phi

    return (rad, theta, phi)