Beispiel #1
0
def circlefrom1Line2Points(edge, p1, p2):
    """circlefrom1Line2Points(edge, Vector, Vector)"""
    p1_p2 = edg(p1, p2)
    s = findIntersection(edge, p1_p2, True, True)
    if not s: return None
    s = s[0]
    v1 = p1.sub(s)
    v2 = p2.sub(s)
    projectedDist = math.sqrt(abs(v1.dot(v2)))
    edgeDir = vec(edge)
    edgeDir.normalize()
    projectedCen1 = Vector.add(s, Vector(edgeDir).multiply(projectedDist))
    projectedCen2 = Vector.add(s, Vector(edgeDir).multiply(-projectedDist))
    perpEdgeDir = edgeDir.cross(Vector(0, 0, 1))
    perpCen1 = Vector.add(projectedCen1, perpEdgeDir)
    perpCen2 = Vector.add(projectedCen2, perpEdgeDir)
    mid = findMidpoint(p1_p2)
    x = DraftVecUtils.crossproduct(vec(p1_p2))
    x.normalize()
    perp_mid = Vector.add(mid, x)
    cen1 = findIntersection(edg(projectedCen1, perpCen1), edg(mid, perp_mid),
                            True, True)
    cen2 = findIntersection(edg(projectedCen2, perpCen2), edg(mid, perp_mid),
                            True, True)
    circles = []
    if cen1:
        radius = DraftVecUtils.dist(projectedCen1, cen1[0])
        circles.append(Part.Circle(cen1[0], NORM, radius))
    if cen2:
        radius = DraftVecUtils.dist(projectedCen2, cen2[0])
        circles.append(Part.Circle(cen2[0], NORM, radius))

    if circles: return circles
    else: return None
Beispiel #2
0
def circleFrom3CircleTangents(circle1, circle2, circle3):
    """Return the circle that is tangent to three other circles.

    This problem is called the 'Problem of Appollonius'.

    A special case is that of 'Soddy circles'.

    To Do
    -----
    Currently not all possible solutions are found, only the Soddy circles.

    * Calc all 6 homothetic centers.
    * Create 3 lines from the inner and 4 from the outer h. center.
    * Calc. the 4 inversion poles of these lines for each circle.
    * Calc. the radical center of the 3 circles.
    * Calc. the intersection points (max. 8) of 4 lines (through each
      inversion pole and the radical center) with the circle.
    * This gives us all the tangent points.
    """
    if (geomType(circle1) != "Circle" and geomType(circle2) != "Circle"
            and geomType(circle3) == "Circle"):
        print("debug: circleFrom3CircleTangents bad input! Must be circles")
        return None

    int12 = findIntersection(circle1, circle2, True, True)
    int23 = findIntersection(circle2, circle3, True, True)
    int31 = findIntersection(circle3, circle1, True, True)

    if int12 and int23 and int31:
        if len(int12) == 1 and len(int23) == 1 and len(int31) == 1:
            # If only one intersection with each circle, Soddy circle

            # r1 = circle1.Curve.Radius
            # r2 = circle2.Curve.Radius
            # r3 = circle3.Curve.Radius
            outerSoddy = outerSoddyCircle(circle1, circle2, circle3)
            # print(str(outerSoddy))  # Debug

            innerSoddy = innerSoddyCircle(circle1, circle2, circle3)
            # print(str(innerSoddy))  # Debug

            circles = []
            if outerSoddy:
                circles.append(outerSoddy)
            if innerSoddy:
                circles.append(innerSoddy)
            return circles

        # Here the rest of the circles should be calculated
        # ...
    else:
        # Some circles are inside each other or an error has occurred.
        return None
Beispiel #3
0
def circleFrom3CircleTangents(circle1, circle2, circle3):
    """
    http://en.wikipedia.org/wiki/Problem_of_Apollonius#Inversive_methods
    http://mathworld.wolfram.com/ApolloniusCircle.html
    http://mathworld.wolfram.com/ApolloniusProblem.html
    """

    if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle") \
    and (geomType(circle3) == "Circle"):
        int12 = findIntersection(circle1, circle2, True, True)
        int23 = findIntersection(circle2, circle3, True, True)
        int31 = findIntersection(circle3, circle1, True, True)

        if int12 and int23 and int31:
            if len(int12) == 1 and len(int23) == 1 and len(int31) == 1:
                # Only one intersection with each circle.
                # => "Soddy Circle" - 2 solutions.
                # http://en.wikipedia.org/wiki/Problem_of_Apollonius#Mutually_tangent_given_circles:_Soddy.27s_circles_and_Descartes.27_theorem
                # http://mathworld.wolfram.com/SoddyCircles.html
                # http://mathworld.wolfram.com/InnerSoddyCenter.html
                # http://mathworld.wolfram.com/OuterSoddyCenter.html

                r1 = circle1.Curve.Radius
                r2 = circle2.Curve.Radius
                r3 = circle3.Curve.Radius
                outerSoddy = outerSoddyCircle(circle1, circle2, circle3)
                #               print(str(outerSoddy) + "\n") # Debug

                innerSoddy = innerSoddyCircle(circle1, circle2, circle3)
                #               print(str(innerSoddy) + "\n") # Debug

                circles = []
                if outerSoddy:
                    circles.append(outerSoddy)
                if innerSoddy:
                    circles.append(innerSoddy)
                return circles

            # @todo Calc all 6 homothetic centers.
            # @todo Create 3 lines from the inner and 4 from the outer h. center.
            # @todo Calc. the 4 inversion poles of these lines for each circle.
            # @todo Calc. the radical center of the 3 circles.
            # @todo Calc. the intersection points (max. 8) of 4 lines (through each inversion pole and the radical center) with the circle.
            #       This gives us all the tangent points.
        else:
            # Some circles are inside each other or an error has occurred.
            return None

    else:
        print("debug: circleFrom3CircleTangents bad parameters!\n")
        # FreeCAD.Console.PrintMessage("debug: circleFrom3CircleTangents bad parameters!\n")
        return None
Beispiel #4
0
def getCircleFromSpline(edge):
    """Return a circle-based edge from a bspline-based edge."""
    if geomType(edge) != "BSplineCurve":
        return None
    if len(edge.Vertexes) != 1:
        return None
    # get 2 points
    p1 = edge.Curve.value(0)
    p2 = edge.Curve.value(math.pi / 2)
    # get 2 tangents
    t1 = edge.Curve.tangent(0)[0]
    t2 = edge.Curve.tangent(math.pi / 2)[0]
    # get normal
    n = p1.cross(p2)
    if DraftVecUtils.isNull(n):
        return None
    # get rays
    r1 = DraftVecUtils.rotate(t1, math.pi / 2, n)
    r2 = DraftVecUtils.rotate(t2, math.pi / 2, n)
    # get center (intersection of rays)
    i = findIntersection(p1, p1.add(r1), p2, p2.add(r2), True, True)
    if not i:
        return None
    c = i[0]
    r = (p1.sub(c)).Length
    circle = Part.makeCircle(r, c, n)
    #print(circle.Curve)
    return circle
Beispiel #5
0
def findRadicalCenter(circle1, circle2, circle3):
    """
    findRadicalCenter(circle1, circle2, circle3):
    Calculates the radical center (also called the power center) of three circles.
    It is the intersection point of the three radical axes of the pairs of circles.

    http://en.wikipedia.org/wiki/Power_center_(geometry)
    http://mathworld.wolfram.com/RadicalCenter.html

    @sa findRadicalAxis
    """
    if (geomType(circle1) == "Circle") and (geomType(circle2) == "Circle"):
        radicalAxis12 = findRadicalAxis(circle1, circle2)
        radicalAxis23 = findRadicalAxis(circle1, circle2)

        if not radicalAxis12 or not radicalAxis23:
            # No radical center could be calculated.
            return None

        int = findIntersection(radicalAxis12, radicalAxis23, True, True)

        if int:
            return int
        else:
            # No radical center could be calculated.
            return None
    else:
        FreeCAD.Console.PrintMessage(
            "debug: findRadicalCenter bad parameters!\n")
        return None
Beispiel #6
0
def findRadicalCenter(circle1, circle2, circle3):
    """Calculate the radical center of three circles.

    It is also called the power center.
    It is the intersection point of the three radical axes of the pairs
    of circles.

    http://en.wikipedia.org/wiki/Power_center_(geometry)
    http://mathworld.wolfram.com/RadicalCenter.html

    See Also
    --------
    findRadicalAxis
    """
    if (geomType(circle1) != "Circle"
            or geomType(circle2) != "Circle"
            or geomType(circle3) != "Circle"):
        print("debug: findRadicalCenter bad parameters! Must be circles.")
        return None

    radicalAxis12 = findRadicalAxis(circle1, circle2)
    radicalAxis23 = findRadicalAxis(circle2, circle3)

    if not radicalAxis12 or not radicalAxis23:
        # No radical center could be calculated.
        return None

    intersect = findIntersection(radicalAxis12, radicalAxis23, True, True)

    if intersect:
        return intersect
    else:
        # No radical center could be calculated.
        return None
Beispiel #7
0
def circleFrom2LinesRadius(edge1, edge2, radius):
    """Retun a list of circles from two edges and one radius.

    It calculates 4 centers.
    """
    intsec = findIntersection(edge1, edge2, True, True)
    if not intsec:
        return None

    intsec = intsec[0]
    bis12 = angleBisection(edge1, edge2)
    bis21 = Part.LineSegment(bis12.Vertexes[0].Point,
                             DraftVecUtils.rotate(vec(bis12), math.pi/2.0))
    ang12 = abs(DraftVecUtils.angle(vec(edge1), vec(edge2)))
    ang21 = math.pi - ang12
    dist12 = radius / math.sin(ang12 * 0.5)
    dist21 = radius / math.sin(ang21 * 0.5)

    circles = []
    cen = App.Vector.add(intsec, vec(bis12).multiply(dist12))
    circles.append(Part.Circle(cen, NORM, radius))

    cen = App.Vector.add(intsec, vec(bis12).multiply(-dist12))
    circles.append(Part.Circle(cen, NORM, radius))

    cen = App.Vector.add(intsec, vec(bis21).multiply(dist21))
    circles.append(Part.Circle(cen, NORM, radius))

    cen = App.Vector.add(intsec, vec(bis21).multiply(-dist21))
    circles.append(Part.Circle(cen, NORM, radius))

    return circles
Beispiel #8
0
def circleFrom3LineTangents(edge1, edge2, edge3):
    """Return a list of circles from three edges.

    It calculates up to 6 possible centers.
    """
    def rot(ed):
        geo = Part.LineSegment(v1(ed),
                               v1(ed).add(DraftVecUtils.rotate(vec(ed),
                                                               math.pi/2)))
        return geo.toShape()

    bis12 = angleBisection(edge1, edge2)
    bis23 = angleBisection(edge2, edge3)
    bis31 = angleBisection(edge3, edge1)
    intersections = []

    intsec = findIntersection(bis12, bis23, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(bis23, bis31, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(bis31, bis12, True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis12), rot(bis23), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis23), rot(bis31), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    intsec = findIntersection(rot(bis31), rot(bis12), True, True)
    if intsec:
        radius = findDistance(intsec[0], edge1).Length
        intersections.append(Part.Circle(intsec[0], NORM, radius))

    circles = []
    for intsec in intersections:
        exists = False
        for cir in circles:
            if DraftVecUtils.equals(cir.Center, intsec.Center):
                exists = True
                break
        if not exists:
            circles.append(intsec)

    if circles:
        return circles
    else:
        return None
Beispiel #9
0
def circleFrom3LineTangents(edge1, edge2, edge3):
    """circleFrom3LineTangents(edge,edge,edge)"""
    def rot(ed):
        return Part.LineSegment(
            v1(ed),
            v1(ed).add(DraftVecUtils.rotate(vec(ed), math.pi / 2))).toShape()

    bis12 = angleBisection(edge1, edge2)
    bis23 = angleBisection(edge2, edge3)
    bis31 = angleBisection(edge3, edge1)
    intersections = []
    int = findIntersection(bis12, bis23, True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    int = findIntersection(bis23, bis31, True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    int = findIntersection(bis31, bis12, True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    int = findIntersection(rot(bis12), rot(bis23), True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    int = findIntersection(rot(bis23), rot(bis31), True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    int = findIntersection(rot(bis31), rot(bis12), True, True)
    if int:
        radius = findDistance(int[0], edge1).Length
        intersections.append(Part.Circle(int[0], NORM, radius))
    circles = []
    for int in intersections:
        exists = False
        for cir in circles:
            if DraftVecUtils.equals(cir.Center, int.Center):
                exists = True
                break
        if not exists:
            circles.append(int)
    if circles:
        return circles
    else:
        return None
Beispiel #10
0
def circleFrom2LinesRadius(edge1, edge2, radius):
    """circleFrom2LinesRadius(edge,edge,radius)"""
    int = findIntersection(edge1, edge2, True, True)
    if not int: return None
    int = int[0]
    bis12 = angleBisection(edge1, edge2)
    bis21 = Part.LineSegment(bis12.Vertexes[0].Point,
                             DraftVecUtils.rotate(vec(bis12), math.pi / 2.0))
    ang12 = abs(DraftVecUtils.angle(vec(edge1), vec(edge2)))
    ang21 = math.pi - ang12
    dist12 = radius / math.sin(ang12 * 0.5)
    dist21 = radius / math.sin(ang21 * 0.5)
    circles = []
    cen = Vector.add(int, vec(bis12).multiply(dist12))
    circles.append(Part.Circle(cen, NORM, radius))
    cen = Vector.add(int, vec(bis12).multiply(-dist12))
    circles.append(Part.Circle(cen, NORM, radius))
    cen = Vector.add(int, vec(bis21).multiply(dist21))
    circles.append(Part.Circle(cen, NORM, radius))
    cen = Vector.add(int, vec(bis21).multiply(-dist21))
    circles.append(Part.Circle(cen, NORM, radius))
    return circles
Beispiel #11
0
def angleBisection(edge1, edge2):
    """angleBisection(edge,edge) - Returns an edge that bisects the angle between the 2 edges."""
    if (geomType(edge1) == "Line") and (geomType(edge2) == "Line"):
        p1 = edge1.Vertexes[0].Point
        p2 = edge1.Vertexes[-1].Point
        p3 = edge2.Vertexes[0].Point
        p4 = edge2.Vertexes[-1].Point
        int = findIntersection(edge1, edge2, True, True)
        if int:
            line1Dir = p2.sub(p1)
            angleDiff = DraftVecUtils.angle(line1Dir, p4.sub(p3))
            ang = angleDiff * 0.5
            origin = int[0]
            line1Dir.normalize()
            dir = DraftVecUtils.rotate(line1Dir, ang)
            return Part.LineSegment(origin, origin.add(dir)).toShape()
        else:
            diff = p3.sub(p1)
            origin = p1.add(diff.multiply(0.5))
            dir = p2.sub(p1)
            dir.normalize()
            return Part.LineSegment(origin, origin.add(dir)).toShape()
    else:
        return None