A bent lever turns about a fixed pin F. One arm runs 13.2 mm from F out to a pin H, the other runs 16.9 mm from F out to a pin G, and the two arms are set at a right angle to each other at F. A straight pull-rod connects pin G to a block whose centre is K; the block slides along a straight rail 20.2 mm to the right of F. Set up coordinates with F at the origin. Place the lever so that pin H is level with F, with the arm FH reaching out to the right and the arm FG standing up above F. In this position the block has been driven to sit -5.4 mm relative to the level of F, measured up the rail. The pull-rod has not been cut to length yet - work out where every pin sits, and how long that rod has to be.

"""Bell crank with the pull-rod length to be found

Oracle formalization for mechh_t4_mechh_bell_crank_derived_0065. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(31)

F, G, H, K = scene.add.points(["F", "G", "H", "K"])

scene.constraint.eq(F.x, 0, description="datum: F is the origin, the fixed pin of the bent lever (x)")
scene.constraint.eq(F.y, 0, description="datum: F is the origin, the fixed pin of the bent lever (y)")
scene.constraint.eq(H.y, F.y, description="pin H is level with the fixed pin F")
scene.constraint.gt(H.x - F.x, 1.0, description="the arm FH reaches out in the +x direction")
scene.constraint.eq(F.distance(H), 13.2, description="the arm FH is 13.2 long")
scene.constraint.eq(F.distance(G), 16.9, description="the arm FG is 16.9 long")
scene.relate.right_angle(G, F, H)
scene.constraint.gt(G.y - F.y, 0.05, description="the arm FG stands up above the fixed pin")
scene.constraint.eq(K.x - F.x, 20.2, description="the block runs on a straight rail 20.2 to the right of F")
scene.constraint.eq(K.y - F.y, -5.4, description="in this position the block sits -5.4 relative to the level of F")


A mechanism is built from three rigid bars pinned together in the plane. Bar 1 turns about a fixed pin A on the bench and carries a moving pin C at its far end. Bar 2 turns about a second fixed pin B and carries a moving pin D at its far end. Bar 3 joins pin C to pin D. The bars are rigid and the two fixed pins never move. Neither fixed pin has been located yet - that is what has to be worked out. As the mechanism is worked through its travel, the two moving pins are required to pass through three matching pairs of positions, measured on the bench grid: C reaches (18.9855, 16.3744) while D is at (39.7057, 11.204); then C reaches (13.5046, 18.8038) while D is at (35.6394, 12.9406); then C reaches (7.5127, 19.0017) while D is at (31.2188, 13.0296). Write down where each of the two fixed pins must be placed.

Report every point as [x, y] in the datum frame described in the text, and every circle as {centre_label: radius}. Give at least 4 decimal places: a stated fact counts as satisfied only when its residual is below 5e-3 mm.

"""Four-bar with both fixed pivots unknown

Oracle formalization for mechh_t4_mechh_fourbar_both_pivots_0001. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(57)

A, B, C1, C2, C3, D1, D2, D3 = scene.add.points(["A", "B", "C1", "C2", "C3", "D1", "D2", "D3"])

scene.constraint.eq(C1.x, 18.9855, description="required position 1 of the moving pin C (x)")
scene.constraint.eq(C1.y, 16.3744, description="required position 1 of the moving pin C (y)")
scene.constraint.eq(C2.x, 13.5046, description="required position 2 of the moving pin C (x)")
scene.constraint.eq(C2.y, 18.8038, description="required position 2 of the moving pin C (y)")
scene.constraint.eq(C3.x, 7.5127, description="required position 3 of the moving pin C (x)")
scene.constraint.eq(C3.y, 19.0017, description="required position 3 of the moving pin C (y)")
scene.constraint.eq(D1.x, 39.7057, description="matching position 1 of the moving pin D (x)")
scene.constraint.eq(D1.y, 11.204, description="matching position 1 of the moving pin D (y)")
scene.constraint.eq(D2.x, 35.6394, description="matching position 2 of the moving pin D (x)")
scene.constraint.eq(D2.y, 12.9406, description="matching position 2 of the moving pin D (y)")
scene.constraint.eq(D3.x, 31.2188, description="matching position 3 of the moving pin D (x)")
scene.constraint.eq(D3.y, 13.0296, description="matching position 3 of the moving pin D (y)")
scene.constraint.eq(A.distance(C1), A.distance(C2), description="bar AC is rigid, so C is the same distance from A in positions 1 and 2")
scene.constraint.eq(A.distance(C1), A.distance(C3), description="bar AC is rigid, so C is the same distance from A in positions 1 and 3")
scene.constraint.eq(B.distance(D1), B.distance(D2), description="bar BD is rigid, so D is the same distance from B in positions 1 and 2")
scene.constraint.eq(B.distance(D1), B.distance(D3), description="bar BD is rigid, so D is the same distance from B in positions 1 and 3")

bar 1 turns about the fixed pin A, so all three positions of C are the SAME distance from A

so A is the circumcentre of the three C positions

the same argument applies independently to B and the three D positions

both pivots must be found this way - neither is given, and neither can be read off the other


A mechanism is built from three rigid bars pinned together in the plane. Bar 1 turns about a fixed pin A on the bench and carries a moving pin C at its far end. Bar 2 turns about a second fixed pin B and carries a moving pin D at its far end. Bar 3 joins pin C to pin D. The bars are rigid and the two fixed pins never move. Neither fixed pin has been located yet - that is what has to be worked out. As the mechanism is worked through its travel, the two moving pins are required to pass through three matching pairs of positions, measured on the bench grid: C reaches (15.7869, 19.0127) while D is at (32.4387, 10.6711); then C reaches (10.6065, 20.7411) while D is at (28.7136, 12.0931); then C reaches (5.1486, 20.5528) while D is at (24.7342, 11.8431). Write down where each of the two fixed pins must be placed.

"""Four-bar with both fixed pivots unknown

Oracle formalization for mechh_t4_mechh_fourbar_both_pivots_0002. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(47)

A, B, C1, C2, C3, D1, D2, D3 = scene.add.points(["A", "B", "C1", "C2", "C3", "D1", "D2", "D3"])

scene.constraint.eq(C1.x, 15.7869, description="required position 1 of the moving pin C (x)")
scene.constraint.eq(C1.y, 19.0127, description="required position 1 of the moving pin C (y)")
scene.constraint.eq(C2.x, 10.6065, description="required position 2 of the moving pin C (x)")
scene.constraint.eq(C2.y, 20.7411, description="required position 2 of the moving pin C (y)")
scene.constraint.eq(C3.x, 5.1486, description="required position 3 of the moving pin C (x)")
scene.constraint.eq(C3.y, 20.5528, description="required position 3 of the moving pin C (y)")
scene.constraint.eq(D1.x, 32.4387, description="matching position 1 of the moving pin D (x)")
scene.constraint.eq(D1.y, 10.6711, description="matching position 1 of the moving pin D (y)")
scene.constraint.eq(D2.x, 28.7136, description="matching position 2 of the moving pin D (x)")
scene.constraint.eq(D2.y, 12.0931, description="matching position 2 of the moving pin D (y)")
scene.constraint.eq(D3.x, 24.7342, description="matching position 3 of the moving pin D (x)")
scene.constraint.eq(D3.y, 11.8431, description="matching position 3 of the moving pin D (y)")
scene.constraint.eq(A.distance(C1), A.distance(C2), description="bar AC is rigid, so C is the same distance from A in positions 1 and 2")
scene.constraint.eq(A.distance(C1), A.distance(C3), description="bar AC is rigid, so C is the same distance from A in positions 1 and 3")
scene.constraint.eq(B.distance(D1), B.distance(D2), description="bar BD is rigid, so D is the same distance from B in positions 1 and 2")
scene.constraint.eq(B.distance(D1), B.distance(D3), description="bar BD is rigid, so D is the same distance from B in positions 1 and 3")


A mechanism is built from three rigid bars pinned together in the plane. Bar 1 turns about a fixed pin A on the bench and carries a moving pin C at its far end. Bar 2 turns about a second fixed pin B and carries a moving pin D at its far end. Bar 3 joins pin C to pin D. The bars are rigid and the two fixed pins never move. Neither fixed pin has been located yet - that is what has to be worked out. As the mechanism is worked through its travel, the two moving pins are required to pass through three matching pairs of positions, measured on the bench grid: C reaches (18.8261, 14.9418) while D is at (35.2283, 15.7443); then C reaches (12.5716, 18.3278) while D is at (29.1967, 16.8908); then C reaches (5.4624, 18.1219) while D is at (23.2649, 15.3077). Write down where each of the two fixed pins must be placed.

"""Four-bar with both fixed pivots unknown

Oracle formalization for mechh_t4_mechh_fourbar_both_pivots_0003. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(51)

A, B, C1, C2, C3, D1, D2, D3 = scene.add.points(["A", "B", "C1", "C2", "C3", "D1", "D2", "D3"])

scene.constraint.eq(C1.x, 18.8261, description="required position 1 of the moving pin C (x)")
scene.constraint.eq(C1.y, 14.9418, description="required position 1 of the moving pin C (y)")
scene.constraint.eq(C2.x, 12.5716, description="required position 2 of the moving pin C (x)")
scene.constraint.eq(C2.y, 18.3278, description="required position 2 of the moving pin C (y)")
scene.constraint.eq(C3.x, 5.4624, description="required position 3 of the moving pin C (x)")
scene.constraint.eq(C3.y, 18.1219, description="required position 3 of the moving pin C (y)")
scene.constraint.eq(D1.x, 35.2283, description="matching position 1 of the moving pin D (x)")
scene.constraint.eq(D1.y, 15.7443, description="matching position 1 of the moving pin D (y)")
scene.constraint.eq(D2.x, 29.1967, description="matching position 2 of the moving pin D (x)")
scene.constraint.eq(D2.y, 16.8908, description="matching position 2 of the moving pin D (y)")
scene.constraint.eq(D3.x, 23.2649, description="matching position 3 of the moving pin D (x)")
scene.constraint.eq(D3.y, 15.3077, description="matching position 3 of the moving pin D (y)")
scene.constraint.eq(A.distance(C1), A.distance(C2), description="bar AC is rigid, so C is the same distance from A in positions 1 and 2")
scene.constraint.eq(A.distance(C1), A.distance(C3), description="bar AC is rigid, so C is the same distance from A in positions 1 and 3")
scene.constraint.eq(B.distance(D1), B.distance(D2), description="bar BD is rigid, so D is the same distance from B in positions 1 and 2")
scene.constraint.eq(B.distance(D1), B.distance(D3), description="bar BD is rigid, so D is the same distance from B in positions 1 and 3")


A mechanism is built from three rigid bars pinned together in the plane. Bar 1 turns about a fixed pin A on the bench and carries a moving pin C at its far end. Bar 2 turns about a second fixed pin B and carries a moving pin D at its far end. Bar 3 joins pin C to pin D. The bars are rigid and the two fixed pins never move. Neither fixed pin has been located yet - that is what has to be worked out. As the mechanism is worked through its travel, the two moving pins are required to pass through three matching pairs of positions, measured on the bench grid: C reaches (21.3491, 14.9782) while D is at (34.995, 18.6944); then C reaches (14.2335, 19.1298) while D is at (30.0432, 18.325); then C reaches (5.9956, 19.1908) while D is at (25.6566, 15.9979). Write down where each of the two fixed pins must be placed.

"""Four-bar with both fixed pivots unknown

Oracle formalization for mechh_t4_mechh_fourbar_both_pivots_0004. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(50)

A, B, C1, C2, C3, D1, D2, D3 = scene.add.points(["A", "B", "C1", "C2", "C3", "D1", "D2", "D3"])

scene.constraint.eq(C1.x, 21.3491, description="required position 1 of the moving pin C (x)")
scene.constraint.eq(C1.y, 14.9782, description="required position 1 of the moving pin C (y)")
scene.constraint.eq(C2.x, 14.2335, description="required position 2 of the moving pin C (x)")
scene.constraint.eq(C2.y, 19.1298, description="required position 2 of the moving pin C (y)")
scene.constraint.eq(C3.x, 5.9956, description="required position 3 of the moving pin C (x)")
scene.constraint.eq(C3.y, 19.1908, description="required position 3 of the moving pin C (y)")
scene.constraint.eq(D1.x, 34.995, description="matching position 1 of the moving pin D (x)")
scene.constraint.eq(D1.y, 18.6944, description="matching position 1 of the moving pin D (y)")
scene.constraint.eq(D2.x, 30.0432, description="matching position 2 of the moving pin D (x)")
scene.constraint.eq(D2.y, 18.325, description="matching position 2 of the moving pin D (y)")
scene.constraint.eq(D3.x, 25.6566, description="matching position 3 of the moving pin D (x)")
scene.constraint.eq(D3.y, 15.9979, description="matching position 3 of the moving pin D (y)")
scene.constraint.eq(A.distance(C1), A.distance(C2), description="bar AC is rigid, so C is the same distance from A in positions 1 and 2")
scene.constraint.eq(A.distance(C1), A.distance(C3), description="bar AC is rigid, so C is the same distance from A in positions 1 and 3")
scene.constraint.eq(B.distance(D1), B.distance(D2), description="bar BD is rigid, so D is the same distance from B in positions 1 and 2")
scene.constraint.eq(B.distance(D1), B.distance(D3), description="bar BD is rigid, so D is the same distance from B in positions 1 and 3")


A mechanism is built from three rigid bars pinned together in the plane. Bar 1 turns about a fixed pin A on the bench and carries a moving pin C at its far end. Bar 2 turns about a second fixed pin B and carries a moving pin D at its far end. Bar 3 joins pin C to pin D. The bars are rigid and the two fixed pins never move. Neither fixed pin has been located yet - that is what has to be worked out. As the mechanism is worked through its travel, the two moving pins are required to pass through three matching pairs of positions, measured on the bench grid: C reaches (17.8448, 16.9825) while D is at (36.1835, 15.0712); then C reaches (11.8502, 18.8603) while D is at (31.6025, 16.8345); then C reaches (5.641, 17.9072) while D is at (26.6973, 16.6497). Write down where each of the two fixed pins must be placed.

"""Four-bar with both fixed pivots unknown

Oracle formalization for mechh_t4_mechh_fourbar_both_pivots_0005. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(52)

A, B, C1, C2, C3, D1, D2, D3 = scene.add.points(["A", "B", "C1", "C2", "C3", "D1", "D2", "D3"])

scene.constraint.eq(C1.x, 17.8448, description="required position 1 of the moving pin C (x)")
scene.constraint.eq(C1.y, 16.9825, description="required position 1 of the moving pin C (y)")
scene.constraint.eq(C2.x, 11.8502, description="required position 2 of the moving pin C (x)")
scene.constraint.eq(C2.y, 18.8603, description="required position 2 of the moving pin C (y)")
scene.constraint.eq(C3.x, 5.641, description="required position 3 of the moving pin C (x)")
scene.constraint.eq(C3.y, 17.9072, description="required position 3 of the moving pin C (y)")
scene.constraint.eq(D1.x, 36.1835, description="matching position 1 of the moving pin D (x)")
scene.constraint.eq(D1.y, 15.0712, description="matching position 1 of the moving pin D (y)")
scene.constraint.eq(D2.x, 31.6025, description="matching position 2 of the moving pin D (x)")
scene.constraint.eq(D2.y, 16.8345, description="matching position 2 of the moving pin D (y)")
scene.constraint.eq(D3.x, 26.6973, description="matching position 3 of the moving pin D (x)")
scene.constraint.eq(D3.y, 16.6497, description="matching position 3 of the moving pin D (y)")
scene.constraint.eq(A.distance(C1), A.distance(C2), description="bar AC is rigid, so C is the same distance from A in positions 1 and 2")
scene.constraint.eq(A.distance(C1), A.distance(C3), description="bar AC is rigid, so C is the same distance from A in positions 1 and 3")
scene.constraint.eq(B.distance(D1), B.distance(D2), description="bar BD is rigid, so D is the same distance from B in positions 1 and 2")
scene.constraint.eq(B.distance(D1), B.distance(D3), description="bar BD is rigid, so D is the same distance from B in positions 1 and 3")


A quick-return drive has a crank 8.7 mm long turning about a fixed centre O, and a long slotted lever pivoted to the bench at S, directly below O and 20.7 mm down from it. Set up coordinates with O at the origin. The crank pin slides in the lever's slot, so it always sits somewhere along the lever between the pivot S and the lever's tip; the lever measures 31.1 mm from S to its tip. As the crank goes round, the lever rocks back and forth between two extreme positions, and it reverses at exactly the moments when the crank has swung as far to one side as it can take the lever - which is when the crank itself lies square to the lever. Show the mechanism at both of those turning points: the crank pin at P1 with the lever tip at T1 for the extreme where the tip has swung to the right, and the crank pin at P2 with the lever tip at T2 for the extreme where it has swung to the left.

"""Quick-return drive at both reversal points

Oracle formalization for mechh_t4_mechh_quick_return_extremes_0071. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(32)

O, S, P1, T1, P2, T2 = scene.add.points(["O", "S", "P1", "T1", "P2", "T2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the crank centre (y)")
scene.constraint.eq(S.x, O.x, description="the lever pivot S is directly below the crank centre")
scene.constraint.eq(O.y - S.y, 20.7, description="the lever pivot S is 20.7 below the crank centre")
scene.constraint.eq(O.distance(P1), 8.7, description="the crank is 8.7 long (first extreme)")
scene.constraint.eq(O.distance(P2), 8.7, description="the crank is 8.7 long (second extreme)")
scene.constraint.eq(S.distance(T1), 31.1, description="the lever measures 31.1 from its pivot to its tip (first extreme)")
scene.constraint.eq(S.distance(T2), 31.1, description="the lever measures 31.1 from its pivot to its tip (second extreme)")
scene.relate.point_lies_on(P1, scene.add.line_segment(S, T1))
scene.relate.point_lies_on(P2, scene.add.line_segment(S, T2))
scene.relate.perpendicular(scene.add.line_segment(O, P1), scene.add.line_segment(S, P1))
scene.relate.perpendicular(scene.add.line_segment(O, P2), scene.add.line_segment(S, P2))
scene.constraint.gt(T1.x - S.x, 0.05, description="the first extreme is the one where the lever tip has swung to the right")
scene.constraint.lt(T2.x - S.x, -0.05, description="the second extreme is the one where the lever tip has swung to the left")

the lever reverses exactly when the crank is square to the lever, which is the geometric condition behind 'as far as it can take it'

so at each extreme, the crank OP is perpendicular to the lever line SP

that makes O, P and S a right-angled triangle with the right angle at P, fixing the crank pin

the lever tip then lies on the ray from S through P at the lever's full length

P1/T1 is the right-hand extreme and P2/T2 the left-hand one


A quick-return drive has a crank 9.6 mm long turning about a fixed centre O, and a long slotted lever pivoted to the bench at S, directly below O and 18.3 mm down from it. Set up coordinates with O at the origin. The crank pin slides in the lever's slot, so it always sits somewhere along the lever between the pivot S and the lever's tip; the lever measures 30.3 mm from S to its tip. As the crank goes round, the lever rocks back and forth between two extreme positions, and it reverses at exactly the moments when the crank has swung as far to one side as it can take the lever - which is when the crank itself lies square to the lever. Show the mechanism at both of those turning points: the crank pin at P1 with the lever tip at T1 for the extreme where the tip has swung to the right, and the crank pin at P2 with the lever tip at T2 for the extreme where it has swung to the left.

"""Quick-return drive at both reversal points

Oracle formalization for mechh_t4_mechh_quick_return_extremes_0072. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(29)

O, S, P1, T1, P2, T2 = scene.add.points(["O", "S", "P1", "T1", "P2", "T2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the crank centre (y)")
scene.constraint.eq(S.x, O.x, description="the lever pivot S is directly below the crank centre")
scene.constraint.eq(O.y - S.y, 18.3, description="the lever pivot S is 18.3 below the crank centre")
scene.constraint.eq(O.distance(P1), 9.6, description="the crank is 9.6 long (first extreme)")
scene.constraint.eq(O.distance(P2), 9.6, description="the crank is 9.6 long (second extreme)")
scene.constraint.eq(S.distance(T1), 30.3, description="the lever measures 30.3 from its pivot to its tip (first extreme)")
scene.constraint.eq(S.distance(T2), 30.3, description="the lever measures 30.3 from its pivot to its tip (second extreme)")
scene.relate.point_lies_on(P1, scene.add.line_segment(S, T1))
scene.relate.point_lies_on(P2, scene.add.line_segment(S, T2))
scene.relate.perpendicular(scene.add.line_segment(O, P1), scene.add.line_segment(S, P1))
scene.relate.perpendicular(scene.add.line_segment(O, P2), scene.add.line_segment(S, P2))
scene.constraint.gt(T1.x - S.x, 0.05, description="the first extreme is the one where the lever tip has swung to the right")
scene.constraint.lt(T2.x - S.x, -0.05, description="the second extreme is the one where the lever tip has swung to the left")


A quick-return drive has a crank 10 mm long turning about a fixed centre O, and a long slotted lever pivoted to the bench at S, directly below O and 19.1 mm down from it. Set up coordinates with O at the origin. The crank pin slides in the lever's slot, so it always sits somewhere along the lever between the pivot S and the lever's tip; the lever measures 29.8 mm from S to its tip. As the crank goes round, the lever rocks back and forth between two extreme positions, and it reverses at exactly the moments when the crank has swung as far to one side as it can take the lever - which is when the crank itself lies square to the lever. Show the mechanism at both of those turning points: the crank pin at P1 with the lever tip at T1 for the extreme where the tip has swung to the right, and the crank pin at P2 with the lever tip at T2 for the extreme where it has swung to the left.

"""Quick-return drive at both reversal points

Oracle formalization for mechh_t4_mechh_quick_return_extremes_0073. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(30)

O, S, P1, T1, P2, T2 = scene.add.points(["O", "S", "P1", "T1", "P2", "T2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the crank centre (y)")
scene.constraint.eq(S.x, O.x, description="the lever pivot S is directly below the crank centre")
scene.constraint.eq(O.y - S.y, 19.1, description="the lever pivot S is 19.1 below the crank centre")
scene.constraint.eq(O.distance(P1), 10, description="the crank is 10 long (first extreme)")
scene.constraint.eq(O.distance(P2), 10, description="the crank is 10 long (second extreme)")
scene.constraint.eq(S.distance(T1), 29.8, description="the lever measures 29.8 from its pivot to its tip (first extreme)")
scene.constraint.eq(S.distance(T2), 29.8, description="the lever measures 29.8 from its pivot to its tip (second extreme)")
scene.relate.point_lies_on(P1, scene.add.line_segment(S, T1))
scene.relate.point_lies_on(P2, scene.add.line_segment(S, T2))
scene.relate.perpendicular(scene.add.line_segment(O, P1), scene.add.line_segment(S, P1))
scene.relate.perpendicular(scene.add.line_segment(O, P2), scene.add.line_segment(S, P2))
scene.constraint.gt(T1.x - S.x, 0.05, description="the first extreme is the one where the lever tip has swung to the right")
scene.constraint.lt(T2.x - S.x, -0.05, description="the second extreme is the one where the lever tip has swung to the left")


A quick-return drive has a crank 10.3 mm long turning about a fixed centre O, and a long slotted lever pivoted to the bench at S, directly below O and 21.2 mm down from it. Set up coordinates with O at the origin. The crank pin slides in the lever's slot, so it always sits somewhere along the lever between the pivot S and the lever's tip; the lever measures 27.3 mm from S to its tip. As the crank goes round, the lever rocks back and forth between two extreme positions, and it reverses at exactly the moments when the crank has swung as far to one side as it can take the lever - which is when the crank itself lies square to the lever. Show the mechanism at both of those turning points: the crank pin at P1 with the lever tip at T1 for the extreme where the tip has swung to the right, and the crank pin at P2 with the lever tip at T2 for the extreme where it has swung to the left.

"""Quick-return drive at both reversal points

Oracle formalization for mechh_t4_mechh_quick_return_extremes_0074. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(33)

O, S, P1, T1, P2, T2 = scene.add.points(["O", "S", "P1", "T1", "P2", "T2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the crank centre (y)")
scene.constraint.eq(S.x, O.x, description="the lever pivot S is directly below the crank centre")
scene.constraint.eq(O.y - S.y, 21.2, description="the lever pivot S is 21.2 below the crank centre")
scene.constraint.eq(O.distance(P1), 10.3, description="the crank is 10.3 long (first extreme)")
scene.constraint.eq(O.distance(P2), 10.3, description="the crank is 10.3 long (second extreme)")
scene.constraint.eq(S.distance(T1), 27.3, description="the lever measures 27.3 from its pivot to its tip (first extreme)")
scene.constraint.eq(S.distance(T2), 27.3, description="the lever measures 27.3 from its pivot to its tip (second extreme)")
scene.relate.point_lies_on(P1, scene.add.line_segment(S, T1))
scene.relate.point_lies_on(P2, scene.add.line_segment(S, T2))
scene.relate.perpendicular(scene.add.line_segment(O, P1), scene.add.line_segment(S, P1))
scene.relate.perpendicular(scene.add.line_segment(O, P2), scene.add.line_segment(S, P2))
scene.constraint.gt(T1.x - S.x, 0.05, description="the first extreme is the one where the lever tip has swung to the right")
scene.constraint.lt(T2.x - S.x, -0.05, description="the second extreme is the one where the lever tip has swung to the left")


A quick-return drive has a crank 7.1 mm long turning about a fixed centre O, and a long slotted lever pivoted to the bench at S, directly below O and 23.8 mm down from it. Set up coordinates with O at the origin. The crank pin slides in the lever's slot, so it always sits somewhere along the lever between the pivot S and the lever's tip; the lever measures 31.4 mm from S to its tip. As the crank goes round, the lever rocks back and forth between two extreme positions, and it reverses at exactly the moments when the crank has swung as far to one side as it can take the lever - which is when the crank itself lies square to the lever. Show the mechanism at both of those turning points: the crank pin at P1 with the lever tip at T1 for the extreme where the tip has swung to the right, and the crank pin at P2 with the lever tip at T2 for the extreme where it has swung to the left.

"""Quick-return drive at both reversal points

Oracle formalization for mechh_t4_mechh_quick_return_extremes_0075. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(36)

O, S, P1, T1, P2, T2 = scene.add.points(["O", "S", "P1", "T1", "P2", "T2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the crank centre (y)")
scene.constraint.eq(S.x, O.x, description="the lever pivot S is directly below the crank centre")
scene.constraint.eq(O.y - S.y, 23.8, description="the lever pivot S is 23.8 below the crank centre")
scene.constraint.eq(O.distance(P1), 7.1, description="the crank is 7.1 long (first extreme)")
scene.constraint.eq(O.distance(P2), 7.1, description="the crank is 7.1 long (second extreme)")
scene.constraint.eq(S.distance(T1), 31.4, description="the lever measures 31.4 from its pivot to its tip (first extreme)")
scene.constraint.eq(S.distance(T2), 31.4, description="the lever measures 31.4 from its pivot to its tip (second extreme)")
scene.relate.point_lies_on(P1, scene.add.line_segment(S, T1))
scene.relate.point_lies_on(P2, scene.add.line_segment(S, T2))
scene.relate.perpendicular(scene.add.line_segment(O, P1), scene.add.line_segment(S, P1))
scene.relate.perpendicular(scene.add.line_segment(O, P2), scene.add.line_segment(S, P2))
scene.constraint.gt(T1.x - S.x, 0.05, description="the first extreme is the one where the lever tip has swung to the right")
scene.constraint.lt(T2.x - S.x, -0.05, description="the second extreme is the one where the lever tip has swung to the left")


A rigid carrier plate has two pins driven into it, P and Q. The plate has to be swung between two working poses by hanging it on two bars, one pinned to the bench at A and carrying P, the other pinned to the bench at B and carrying Q. Both bench pins must be mounted somewhere on the bench base line, which is the line at height 0 on the bench grid. In the first pose, P sits at (13, 11.4) and Q sits at (25.7775, 18.8683). In the second pose, P has moved to (14.7237, 8.6862) and Q to (22.8066, 21.0841). Both bars are rigid, so neither changes length as the plate swings. Work out where the two bench pins A and B have to go.

"""Rigid-body guidance through two poses

Oracle formalization for mechh_t4_mechh_rigid_body_guidance_0011. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(39)

A, B, P1, Q1, P2, Q2 = scene.add.points(["A", "B", "P1", "Q1", "P2", "Q2"])

scene.constraint.eq(P1.x, 13, description="first pose, pin P (x)")
scene.constraint.eq(P1.y, 11.4, description="first pose, pin P (y)")
scene.constraint.eq(Q1.x, 25.7775, description="first pose, pin Q (x)")
scene.constraint.eq(Q1.y, 18.8683, description="first pose, pin Q (y)")
scene.constraint.eq(P2.x, 14.7237, description="second pose, pin P (x)")
scene.constraint.eq(P2.y, 8.6862, description="second pose, pin P (y)")
scene.constraint.eq(Q2.x, 22.8066, description="second pose, pin Q (x)")
scene.constraint.eq(Q2.y, 21.0841, description="second pose, pin Q (y)")
scene.constraint.eq(A.y, 0, description="the fixed pin A is mounted on the bench base line, the line y = 0")
scene.constraint.eq(B.y, 0, description="the fixed pin B is mounted on the bench base line, the line y = 0")
scene.constraint.eq(A.distance(P1), A.distance(P2), description="the bar from A to P is rigid, so P is the same distance from A in both poses")
scene.constraint.eq(B.distance(Q1), B.distance(Q2), description="the bar from B to Q is rigid, so Q is the same distance from B in both poses")

the bar from A to P is rigid and A is fixed, so P is the same distance from A in both poses

that puts A on the perpendicular bisector of the segment joining P's two positions

combined with 'A is on the base line', that pins A completely

the identical argument, applied separately to Q, pins B - the two pivots are found independently


A rigid carrier plate has two pins driven into it, P and Q. The plate has to be swung between two working poses by hanging it on two bars, one pinned to the bench at A and carrying P, the other pinned to the bench at B and carrying Q. Both bench pins must be mounted somewhere on the bench base line, which is the line at height 0 on the bench grid. In the first pose, P sits at (10.7, 12.8) and Q sits at (24.8014, 15.7174). In the second pose, P has moved to (12.6307, 8.9079) and Q to (22.407, 19.4806). Both bars are rigid, so neither changes length as the plate swings. Work out where the two bench pins A and B have to go.

"""Rigid-body guidance through two poses

Oracle formalization for mechh_t4_mechh_rigid_body_guidance_0012. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(37)

A, B, P1, Q1, P2, Q2 = scene.add.points(["A", "B", "P1", "Q1", "P2", "Q2"])

scene.constraint.eq(P1.x, 10.7, description="first pose, pin P (x)")
scene.constraint.eq(P1.y, 12.8, description="first pose, pin P (y)")
scene.constraint.eq(Q1.x, 24.8014, description="first pose, pin Q (x)")
scene.constraint.eq(Q1.y, 15.7174, description="first pose, pin Q (y)")
scene.constraint.eq(P2.x, 12.6307, description="second pose, pin P (x)")
scene.constraint.eq(P2.y, 8.9079, description="second pose, pin P (y)")
scene.constraint.eq(Q2.x, 22.407, description="second pose, pin Q (x)")
scene.constraint.eq(Q2.y, 19.4806, description="second pose, pin Q (y)")
scene.constraint.eq(A.y, 0, description="the fixed pin A is mounted on the bench base line, the line y = 0")
scene.constraint.eq(B.y, 0, description="the fixed pin B is mounted on the bench base line, the line y = 0")
scene.constraint.eq(A.distance(P1), A.distance(P2), description="the bar from A to P is rigid, so P is the same distance from A in both poses")
scene.constraint.eq(B.distance(Q1), B.distance(Q2), description="the bar from B to Q is rigid, so Q is the same distance from B in both poses")


A rigid carrier plate has two pins driven into it, P and Q. The plate has to be swung between two working poses by hanging it on two bars, one pinned to the bench at A and carrying P, the other pinned to the bench at B and carrying Q. Both bench pins must be mounted somewhere on the bench base line, which is the line at height 0 on the bench grid. In the first pose, P sits at (11, 12.3) and Q sits at (19.1215, 17.2287). In the second pose, P has moved to (13.0629, 8.8146) and Q to (16.501, 17.6707). Both bars are rigid, so neither changes length as the plate swings. Work out where the two bench pins A and B have to go.

"""Rigid-body guidance through two poses

Oracle formalization for mechh_t4_mechh_rigid_body_guidance_0013. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(30)

A, B, P1, Q1, P2, Q2 = scene.add.points(["A", "B", "P1", "Q1", "P2", "Q2"])

scene.constraint.eq(P1.x, 11, description="first pose, pin P (x)")
scene.constraint.eq(P1.y, 12.3, description="first pose, pin P (y)")
scene.constraint.eq(Q1.x, 19.1215, description="first pose, pin Q (x)")
scene.constraint.eq(Q1.y, 17.2287, description="first pose, pin Q (y)")
scene.constraint.eq(P2.x, 13.0629, description="second pose, pin P (x)")
scene.constraint.eq(P2.y, 8.8146, description="second pose, pin P (y)")
scene.constraint.eq(Q2.x, 16.501, description="second pose, pin Q (x)")
scene.constraint.eq(Q2.y, 17.6707, description="second pose, pin Q (y)")
scene.constraint.eq(A.y, 0, description="the fixed pin A is mounted on the bench base line, the line y = 0")
scene.constraint.eq(B.y, 0, description="the fixed pin B is mounted on the bench base line, the line y = 0")
scene.constraint.eq(A.distance(P1), A.distance(P2), description="the bar from A to P is rigid, so P is the same distance from A in both poses")
scene.constraint.eq(B.distance(Q1), B.distance(Q2), description="the bar from B to Q is rigid, so Q is the same distance from B in both poses")


A rigid carrier plate has two pins driven into it, P and Q. The plate has to be swung between two working poses by hanging it on two bars, one pinned to the bench at A and carrying P, the other pinned to the bench at B and carrying Q. Both bench pins must be mounted somewhere on the bench base line, which is the line at height 0 on the bench grid. In the first pose, P sits at (9.1, 10.1) and Q sits at (22.0426, 14.2771). In the second pose, P has moved to (11.2469, 8.0938) and Q to (20.1216, 18.3992). Both bars are rigid, so neither changes length as the plate swings. Work out where the two bench pins A and B have to go.

"""Rigid-body guidance through two poses

Oracle formalization for mechh_t4_mechh_rigid_body_guidance_0014. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(34)

A, B, P1, Q1, P2, Q2 = scene.add.points(["A", "B", "P1", "Q1", "P2", "Q2"])

scene.constraint.eq(P1.x, 9.1, description="first pose, pin P (x)")
scene.constraint.eq(P1.y, 10.1, description="first pose, pin P (y)")
scene.constraint.eq(Q1.x, 22.0426, description="first pose, pin Q (x)")
scene.constraint.eq(Q1.y, 14.2771, description="first pose, pin Q (y)")
scene.constraint.eq(P2.x, 11.2469, description="second pose, pin P (x)")
scene.constraint.eq(P2.y, 8.0938, description="second pose, pin P (y)")
scene.constraint.eq(Q2.x, 20.1216, description="second pose, pin Q (x)")
scene.constraint.eq(Q2.y, 18.3992, description="second pose, pin Q (y)")
scene.constraint.eq(A.y, 0, description="the fixed pin A is mounted on the bench base line, the line y = 0")
scene.constraint.eq(B.y, 0, description="the fixed pin B is mounted on the bench base line, the line y = 0")
scene.constraint.eq(A.distance(P1), A.distance(P2), description="the bar from A to P is rigid, so P is the same distance from A in both poses")
scene.constraint.eq(B.distance(Q1), B.distance(Q2), description="the bar from B to Q is rigid, so Q is the same distance from B in both poses")


A rigid carrier plate has two pins driven into it, P and Q. The plate has to be swung between two working poses by hanging it on two bars, one pinned to the bench at A and carrying P, the other pinned to the bench at B and carrying Q. Both bench pins must be mounted somewhere on the bench base line, which is the line at height 0 on the bench grid. In the first pose, P sits at (9.4, 11.7) and Q sits at (18.362, 16.9765). In the second pose, P has moved to (11.3119, 9.3569) and Q to (15.4184, 18.9118). Both bars are rigid, so neither changes length as the plate swings. Work out where the two bench pins A and B have to go.

"""Rigid-body guidance through two poses

Oracle formalization for mechh_t4_mechh_rigid_body_guidance_0015. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(30)

A, B, P1, Q1, P2, Q2 = scene.add.points(["A", "B", "P1", "Q1", "P2", "Q2"])

scene.constraint.eq(P1.x, 9.4, description="first pose, pin P (x)")
scene.constraint.eq(P1.y, 11.7, description="first pose, pin P (y)")
scene.constraint.eq(Q1.x, 18.362, description="first pose, pin Q (x)")
scene.constraint.eq(Q1.y, 16.9765, description="first pose, pin Q (y)")
scene.constraint.eq(P2.x, 11.3119, description="second pose, pin P (x)")
scene.constraint.eq(P2.y, 9.3569, description="second pose, pin P (y)")
scene.constraint.eq(Q2.x, 15.4184, description="second pose, pin Q (x)")
scene.constraint.eq(Q2.y, 18.9118, description="second pose, pin Q (y)")
scene.constraint.eq(A.y, 0, description="the fixed pin A is mounted on the bench base line, the line y = 0")
scene.constraint.eq(B.y, 0, description="the fixed pin B is mounted on the bench base line, the line y = 0")
scene.constraint.eq(A.distance(P1), A.distance(P2), description="the bar from A to P is rigid, so P is the same distance from A in both poses")
scene.constraint.eq(B.distance(Q1), B.distance(Q2), description="the bar from B to Q is rigid, so Q is the same distance from B in both poses")


Two straight bars of different lengths are crossed over each other and pinned together at a single point X. The first bar is 36.3 mm long and the pin sits 17.424 mm along it from its lower end; the second bar is 28.2 mm long and the pin sits 16.638 mm along that one from its lower end - so the pin is NOT at the middle of either bar. The lower end of the first bar is F1 and the lower end of the second is F2; both rest on the same flat floor, a distance apart. The upper ends are U1 on the first bar and U2 on the second, and both bars run upward from the floor through the crossing pin. Set up coordinates with F1 at the origin and the floor as the line through it. Arrange the pair so that the crossing pin X sits 8.7 mm above the floor, with F2 to the right of F1.

"""Scissor pair with unequal bars pinned off-centre

Oracle formalization for mechh_t4_mechh_scissor_unequal_0031. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(46)

F1, F2, U1, U2, X = scene.add.points(["F1", "F2", "U1", "U2", "X"])

scene.constraint.eq(F1.x, 0, description="datum: F1 is the origin, the lower end of the first bar (x)")
scene.constraint.eq(F1.y, 0, description="datum: F1 is the origin, the lower end of the first bar (y)")
scene.constraint.eq(F2.y, F1.y, description="both lower ends rest on the same flat floor")
scene.constraint.gt(F2.x - F1.x, 3.0, description="the two lower ends rest apart from each other on the floor")
scene.constraint.eq(F1.distance(U1), 36.3, description="the first bar is 36.3 long")
scene.constraint.eq(F2.distance(U2), 28.2, description="the second bar is 28.2 long")
scene.relate.point_lies_on(X, scene.add.line_segment(F1, U1))
scene.relate.point_lies_on(X, scene.add.line_segment(F2, U2))
scene.constraint.eq(F1.distance(X), 17.424, description="the crossing pin is 17.424 along the first bar from its lower end")
scene.constraint.eq(F2.distance(X), 16.638, description="the crossing pin is 16.638 along the second bar from its lower end")
scene.constraint.eq(X.y - F1.y, 8.7, description="the crossing pin sits 8.7 above the floor")
scene.constraint.gt(U1.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")
scene.constraint.gt(U2.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")

the pin is NOT the midpoint here, so the usual 'upper end is twice the pin height' shortcut does not apply

each lower end is sqrt(its own pin distance squared minus the pin height squared) horizontally from X

each upper end lies on the same straight line out through X, at its own bar length from its lower end

the two bars have different lengths AND different pin distances, so the two halves are not mirror images

F2 lies to the right of F1, which picks which side the second bar leans


Two straight bars of different lengths are crossed over each other and pinned together at a single point X. The first bar is 28.1 mm long and the pin sits 15.455 mm along it from its lower end; the second bar is 35.6 mm long and the pin sits 16.732 mm along that one from its lower end - so the pin is NOT at the middle of either bar. The lower end of the first bar is F1 and the lower end of the second is F2; both rest on the same flat floor, a distance apart. The upper ends are U1 on the first bar and U2 on the second, and both bars run upward from the floor through the crossing pin. Set up coordinates with F1 at the origin and the floor as the line through it. Arrange the pair so that the crossing pin X sits 8.9 mm above the floor, with F2 to the right of F1.

"""Scissor pair with unequal bars pinned off-centre

Oracle formalization for mechh_t4_mechh_scissor_unequal_0032. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(40)

F1, F2, U1, U2, X = scene.add.points(["F1", "F2", "U1", "U2", "X"])

scene.constraint.eq(F1.x, 0, description="datum: F1 is the origin, the lower end of the first bar (x)")
scene.constraint.eq(F1.y, 0, description="datum: F1 is the origin, the lower end of the first bar (y)")
scene.constraint.eq(F2.y, F1.y, description="both lower ends rest on the same flat floor")
scene.constraint.gt(F2.x - F1.x, 3.0, description="the two lower ends rest apart from each other on the floor")
scene.constraint.eq(F1.distance(U1), 28.1, description="the first bar is 28.1 long")
scene.constraint.eq(F2.distance(U2), 35.6, description="the second bar is 35.6 long")
scene.relate.point_lies_on(X, scene.add.line_segment(F1, U1))
scene.relate.point_lies_on(X, scene.add.line_segment(F2, U2))
scene.constraint.eq(F1.distance(X), 15.455, description="the crossing pin is 15.455 along the first bar from its lower end")
scene.constraint.eq(F2.distance(X), 16.732, description="the crossing pin is 16.732 along the second bar from its lower end")
scene.constraint.eq(X.y - F1.y, 8.9, description="the crossing pin sits 8.9 above the floor")
scene.constraint.gt(U1.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")
scene.constraint.gt(U2.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")


Two straight bars of different lengths are crossed over each other and pinned together at a single point X. The first bar is 31 mm long and the pin sits 13.02 mm along it from its lower end; the second bar is 28.8 mm long and the pin sits 13.248 mm along that one from its lower end - so the pin is NOT at the middle of either bar. The lower end of the first bar is F1 and the lower end of the second is F2; both rest on the same flat floor, a distance apart. The upper ends are U1 on the first bar and U2 on the second, and both bars run upward from the floor through the crossing pin. Set up coordinates with F1 at the origin and the floor as the line through it. Arrange the pair so that the crossing pin X sits 8.3 mm above the floor, with F2 to the right of F1.

"""Scissor pair with unequal bars pinned off-centre

Oracle formalization for mechh_t4_mechh_scissor_unequal_0033. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(36)

F1, F2, U1, U2, X = scene.add.points(["F1", "F2", "U1", "U2", "X"])

scene.constraint.eq(F1.x, 0, description="datum: F1 is the origin, the lower end of the first bar (x)")
scene.constraint.eq(F1.y, 0, description="datum: F1 is the origin, the lower end of the first bar (y)")
scene.constraint.eq(F2.y, F1.y, description="both lower ends rest on the same flat floor")
scene.constraint.gt(F2.x - F1.x, 3.0, description="the two lower ends rest apart from each other on the floor")
scene.constraint.eq(F1.distance(U1), 31, description="the first bar is 31 long")
scene.constraint.eq(F2.distance(U2), 28.8, description="the second bar is 28.8 long")
scene.relate.point_lies_on(X, scene.add.line_segment(F1, U1))
scene.relate.point_lies_on(X, scene.add.line_segment(F2, U2))
scene.constraint.eq(F1.distance(X), 13.02, description="the crossing pin is 13.02 along the first bar from its lower end")
scene.constraint.eq(F2.distance(X), 13.248, description="the crossing pin is 13.248 along the second bar from its lower end")
scene.constraint.eq(X.y - F1.y, 8.3, description="the crossing pin sits 8.3 above the floor")
scene.constraint.gt(U1.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")
scene.constraint.gt(U2.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")


Two straight bars of different lengths are crossed over each other and pinned together at a single point X. The first bar is 35.4 mm long and the pin sits 17.7 mm along it from its lower end; the second bar is 37.2 mm long and the pin sits 16.368 mm along that one from its lower end - so the pin is NOT at the middle of either bar. The lower end of the first bar is F1 and the lower end of the second is F2; both rest on the same flat floor, a distance apart. The upper ends are U1 on the first bar and U2 on the second, and both bars run upward from the floor through the crossing pin. Set up coordinates with F1 at the origin and the floor as the line through it. Arrange the pair so that the crossing pin X sits 12.6 mm above the floor, with F2 to the right of F1.

"""Scissor pair with unequal bars pinned off-centre

Oracle formalization for mechh_t4_mechh_scissor_unequal_0034. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(42)

F1, F2, U1, U2, X = scene.add.points(["F1", "F2", "U1", "U2", "X"])

scene.constraint.eq(F1.x, 0, description="datum: F1 is the origin, the lower end of the first bar (x)")
scene.constraint.eq(F1.y, 0, description="datum: F1 is the origin, the lower end of the first bar (y)")
scene.constraint.eq(F2.y, F1.y, description="both lower ends rest on the same flat floor")
scene.constraint.gt(F2.x - F1.x, 3.0, description="the two lower ends rest apart from each other on the floor")
scene.constraint.eq(F1.distance(U1), 35.4, description="the first bar is 35.4 long")
scene.constraint.eq(F2.distance(U2), 37.2, description="the second bar is 37.2 long")
scene.relate.point_lies_on(X, scene.add.line_segment(F1, U1))
scene.relate.point_lies_on(X, scene.add.line_segment(F2, U2))
scene.constraint.eq(F1.distance(X), 17.7, description="the crossing pin is 17.7 along the first bar from its lower end")
scene.constraint.eq(F2.distance(X), 16.368, description="the crossing pin is 16.368 along the second bar from its lower end")
scene.constraint.eq(X.y - F1.y, 12.6, description="the crossing pin sits 12.6 above the floor")
scene.constraint.gt(U1.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")
scene.constraint.gt(U2.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")


Two straight bars of different lengths are crossed over each other and pinned together at a single point X. The first bar is 31.5 mm long and the pin sits 15.12 mm along it from its lower end; the second bar is 28.4 mm long and the pin sits 15.336 mm along that one from its lower end - so the pin is NOT at the middle of either bar. The lower end of the first bar is F1 and the lower end of the second is F2; both rest on the same flat floor, a distance apart. The upper ends are U1 on the first bar and U2 on the second, and both bars run upward from the floor through the crossing pin. Set up coordinates with F1 at the origin and the floor as the line through it. Arrange the pair so that the crossing pin X sits 11.4 mm above the floor, with F2 to the right of F1.

"""Scissor pair with unequal bars pinned off-centre

Oracle formalization for mechh_t4_mechh_scissor_unequal_0035. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(36)

F1, F2, U1, U2, X = scene.add.points(["F1", "F2", "U1", "U2", "X"])

scene.constraint.eq(F1.x, 0, description="datum: F1 is the origin, the lower end of the first bar (x)")
scene.constraint.eq(F1.y, 0, description="datum: F1 is the origin, the lower end of the first bar (y)")
scene.constraint.eq(F2.y, F1.y, description="both lower ends rest on the same flat floor")
scene.constraint.gt(F2.x - F1.x, 3.0, description="the two lower ends rest apart from each other on the floor")
scene.constraint.eq(F1.distance(U1), 31.5, description="the first bar is 31.5 long")
scene.constraint.eq(F2.distance(U2), 28.4, description="the second bar is 28.4 long")
scene.relate.point_lies_on(X, scene.add.line_segment(F1, U1))
scene.relate.point_lies_on(X, scene.add.line_segment(F2, U2))
scene.constraint.eq(F1.distance(X), 15.12, description="the crossing pin is 15.12 along the first bar from its lower end")
scene.constraint.eq(F2.distance(X), 15.336, description="the crossing pin is 15.336 along the second bar from its lower end")
scene.constraint.eq(X.y - F1.y, 11.4, description="the crossing pin sits 11.4 above the floor")
scene.constraint.gt(U1.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")
scene.constraint.gt(U2.y - X.y, 0.05, description="both bars run upward from the floor through the crossing pin")


A crank 9.7 mm long turns about a fixed centre O and drives a block along a straight rail through a connecting rod 30.6 mm long. Set up coordinates with O at the origin; the rail runs 2.6 mm above the level of O. The mechanism is to be shown at the two ends of the block's travel - the outermost and innermost positions the block can reach, which are exactly the two positions where the crank and the connecting rod fall into one straight line. At the outer position the crank pin A1 lies between O and the block centre B1, with the crank and rod stretched out end to end. At the inner position the crank has come round so that O itself lies between the crank pin A2 and the block centre B2, with the crank folded back along the rod. Both extreme positions are on the positive x side of the crank centre.

"""Slider-crank at both ends of its travel

Oracle formalization for mechh_t4_mechh_slider_dead_centres_0021. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(57)

O, A1, B1, A2, B2 = scene.add.points(["O", "A1", "B1", "A2", "B2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the fixed crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the fixed crank centre (y)")
scene.constraint.eq(O.distance(A1), 9.7, description="the crank is 9.7 long (outer position)")
scene.constraint.eq(A1.distance(B1), 30.6, description="the connecting rod is 30.6 long (outer position)")
scene.constraint.eq(B1.y, 2.6, description="the block runs on a straight rail 2.6 above the level of O (outer position)")
scene.relate.point_lies_on(A1, scene.add.line_segment(O, B1))
scene.constraint.eq(O.distance(A2), 9.7, description="the crank is 9.7 long (inner position)")
scene.constraint.eq(A2.distance(B2), 30.6, description="the connecting rod is 30.6 long (inner position)")
scene.constraint.eq(B2.y, 2.6, description="the block runs on the same rail 2.6 above the level of O (inner position)")
scene.relate.point_lies_on(O, scene.add.line_segment(A2, B2))
scene.constraint.gt(B1.x, 0.05, description="both extreme positions are on the +x side of the crank centre")
scene.constraint.gt(B2.x, 0.05, description="both extreme positions are on the +x side of the crank centre")

the ends of travel are exactly where the crank and the connecting rod become collinear

stretched out, the distance from O to the block is crank + rod

folded back, that distance is rod - crank

the block is then where a circle of that radius about O cuts the rail line, and the crank pin sits on the same straight line at the crank length from O


A crank 7.5 mm long turns about a fixed centre O and drives a block along a straight rail through a connecting rod 24.5 mm long. Set up coordinates with O at the origin; the rail runs 5.6 mm above the level of O. The mechanism is to be shown at the two ends of the block's travel - the outermost and innermost positions the block can reach, which are exactly the two positions where the crank and the connecting rod fall into one straight line. At the outer position the crank pin A1 lies between O and the block centre B1, with the crank and rod stretched out end to end. At the inner position the crank has come round so that O itself lies between the crank pin A2 and the block centre B2, with the crank folded back along the rod. Both extreme positions are on the positive x side of the crank centre.

"""Slider-crank at both ends of its travel

Oracle formalization for mechh_t4_mechh_slider_dead_centres_0022. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(46)

O, A1, B1, A2, B2 = scene.add.points(["O", "A1", "B1", "A2", "B2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the fixed crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the fixed crank centre (y)")
scene.constraint.eq(O.distance(A1), 7.5, description="the crank is 7.5 long (outer position)")
scene.constraint.eq(A1.distance(B1), 24.5, description="the connecting rod is 24.5 long (outer position)")
scene.constraint.eq(B1.y, 5.6, description="the block runs on a straight rail 5.6 above the level of O (outer position)")
scene.relate.point_lies_on(A1, scene.add.line_segment(O, B1))
scene.constraint.eq(O.distance(A2), 7.5, description="the crank is 7.5 long (inner position)")
scene.constraint.eq(A2.distance(B2), 24.5, description="the connecting rod is 24.5 long (inner position)")
scene.constraint.eq(B2.y, 5.6, description="the block runs on the same rail 5.6 above the level of O (inner position)")
scene.relate.point_lies_on(O, scene.add.line_segment(A2, B2))
scene.constraint.gt(B1.x, 0.05, description="both extreme positions are on the +x side of the crank centre")
scene.constraint.gt(B2.x, 0.05, description="both extreme positions are on the +x side of the crank centre")


A crank 7.5 mm long turns about a fixed centre O and drives a block along a straight rail through a connecting rod 27.2 mm long. Set up coordinates with O at the origin; the rail runs 6.4 mm above the level of O. The mechanism is to be shown at the two ends of the block's travel - the outermost and innermost positions the block can reach, which are exactly the two positions where the crank and the connecting rod fall into one straight line. At the outer position the crank pin A1 lies between O and the block centre B1, with the crank and rod stretched out end to end. At the inner position the crank has come round so that O itself lies between the crank pin A2 and the block centre B2, with the crank folded back along the rod. Both extreme positions are on the positive x side of the crank centre.

"""Slider-crank at both ends of its travel

Oracle formalization for mechh_t4_mechh_slider_dead_centres_0023. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(49)

O, A1, B1, A2, B2 = scene.add.points(["O", "A1", "B1", "A2", "B2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the fixed crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the fixed crank centre (y)")
scene.constraint.eq(O.distance(A1), 7.5, description="the crank is 7.5 long (outer position)")
scene.constraint.eq(A1.distance(B1), 27.2, description="the connecting rod is 27.2 long (outer position)")
scene.constraint.eq(B1.y, 6.4, description="the block runs on a straight rail 6.4 above the level of O (outer position)")
scene.relate.point_lies_on(A1, scene.add.line_segment(O, B1))
scene.constraint.eq(O.distance(A2), 7.5, description="the crank is 7.5 long (inner position)")
scene.constraint.eq(A2.distance(B2), 27.2, description="the connecting rod is 27.2 long (inner position)")
scene.constraint.eq(B2.y, 6.4, description="the block runs on the same rail 6.4 above the level of O (inner position)")
scene.relate.point_lies_on(O, scene.add.line_segment(A2, B2))
scene.constraint.gt(B1.x, 0.05, description="both extreme positions are on the +x side of the crank centre")
scene.constraint.gt(B2.x, 0.05, description="both extreme positions are on the +x side of the crank centre")


A crank 8.2 mm long turns about a fixed centre O and drives a block along a straight rail through a connecting rod 21.6 mm long. Set up coordinates with O at the origin; the rail runs 1.2 mm above the level of O. The mechanism is to be shown at the two ends of the block's travel - the outermost and innermost positions the block can reach, which are exactly the two positions where the crank and the connecting rod fall into one straight line. At the outer position the crank pin A1 lies between O and the block centre B1, with the crank and rod stretched out end to end. At the inner position the crank has come round so that O itself lies between the crank pin A2 and the block centre B2, with the crank folded back along the rod. Both extreme positions are on the positive x side of the crank centre.

"""Slider-crank at both ends of its travel

Oracle formalization for mechh_t4_mechh_slider_dead_centres_0024. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(44)

O, A1, B1, A2, B2 = scene.add.points(["O", "A1", "B1", "A2", "B2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the fixed crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the fixed crank centre (y)")
scene.constraint.eq(O.distance(A1), 8.2, description="the crank is 8.2 long (outer position)")
scene.constraint.eq(A1.distance(B1), 21.6, description="the connecting rod is 21.6 long (outer position)")
scene.constraint.eq(B1.y, 1.2, description="the block runs on a straight rail 1.2 above the level of O (outer position)")
scene.relate.point_lies_on(A1, scene.add.line_segment(O, B1))
scene.constraint.eq(O.distance(A2), 8.2, description="the crank is 8.2 long (inner position)")
scene.constraint.eq(A2.distance(B2), 21.6, description="the connecting rod is 21.6 long (inner position)")
scene.constraint.eq(B2.y, 1.2, description="the block runs on the same rail 1.2 above the level of O (inner position)")
scene.relate.point_lies_on(O, scene.add.line_segment(A2, B2))
scene.constraint.gt(B1.x, 0.05, description="both extreme positions are on the +x side of the crank centre")
scene.constraint.gt(B2.x, 0.05, description="both extreme positions are on the +x side of the crank centre")


A crank 8.2 mm long turns about a fixed centre O and drives a block along a straight rail through a connecting rod 27 mm long. Set up coordinates with O at the origin; the rail runs -0.9 mm above the level of O. The mechanism is to be shown at the two ends of the block's travel - the outermost and innermost positions the block can reach, which are exactly the two positions where the crank and the connecting rod fall into one straight line. At the outer position the crank pin A1 lies between O and the block centre B1, with the crank and rod stretched out end to end. At the inner position the crank has come round so that O itself lies between the crank pin A2 and the block centre B2, with the crank folded back along the rod. Both extreme positions are on the positive x side of the crank centre.

"""Slider-crank at both ends of its travel

Oracle formalization for mechh_t4_mechh_slider_dead_centres_0025. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(51)

O, A1, B1, A2, B2 = scene.add.points(["O", "A1", "B1", "A2", "B2"])

scene.constraint.eq(O.x, 0, description="datum: O is the origin, the fixed crank centre (x)")
scene.constraint.eq(O.y, 0, description="datum: O is the origin, the fixed crank centre (y)")
scene.constraint.eq(O.distance(A1), 8.2, description="the crank is 8.2 long (outer position)")
scene.constraint.eq(A1.distance(B1), 27, description="the connecting rod is 27 long (outer position)")
scene.constraint.eq(B1.y, -0.9, description="the block runs on a straight rail -0.9 above the level of O (outer position)")
scene.relate.point_lies_on(A1, scene.add.line_segment(O, B1))
scene.constraint.eq(O.distance(A2), 8.2, description="the crank is 8.2 long (inner position)")
scene.constraint.eq(A2.distance(B2), 27, description="the connecting rod is 27 long (inner position)")
scene.constraint.eq(B2.y, -0.9, description="the block runs on the same rail -0.9 above the level of O (inner position)")
scene.relate.point_lies_on(O, scene.add.line_segment(A2, B2))
scene.constraint.gt(B1.x, 0.05, description="both extreme positions are on the +x side of the crank centre")
scene.constraint.gt(B2.x, 0.05, description="both extreme positions are on the +x side of the crank centre")


A toggle clamp is made of two bars. The first is pinned to the bench at a fixed pin J and is 13.1 mm long, ending at a pin K. The second runs from K out to a clamping pad at L. Set up coordinates with J at the origin. The pad has to reach the point (26.9, -9.2) on the workpiece, and in that clamped position the angle at pin K, measured between the two bars, must come out at 160 degrees. The length of the second bar has not been decided yet - it has to be chosen to make that happen. The elbow at K stands above the straight line from J to the pad.

"""Toggle clamp with the second bar length to be found

Oracle formalization for mechh_t4_mechh_toggle_derived_bar_0041. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(40)

J, K, L = scene.add.points(["J", "K", "L"])

scene.constraint.eq(J.x, 0, description="datum: J is the origin, the fixed pin of the clamp (x)")
scene.constraint.eq(J.y, 0, description="datum: J is the origin, the fixed pin of the clamp (y)")
scene.constraint.eq(L.x, 26.9, description="the clamping pad has to reach this point on the workpiece (x)")
scene.constraint.eq(L.y, -9.2, description="the clamping pad has to reach this point on the workpiece (y)")
scene.constraint.eq(J.distance(K), 13.1, description="the first bar JK is 13.1 long")
scene.constraint.eq(scene.add.angle(J, K, L).value, 160, description="in the clamped position the angle at pin K, between the two bars, is 160 degrees")
scene.constraint.gt(cross(J, L, K), 0.05, description="the elbow at K stands above the straight line from J to the pad")

the second bar's length is NOT given - it is what makes the stated angle come out right

the distance from J to the pad follows straight from the pad's stated position

the cosine rule on the angle at K then gives a QUADRATIC in the unknown bar length, not a direct formula

K itself is where a circle of the first bar's length about J meets a circle of the derived length about the pad

the elbow stands above the line JL, which picks one of the two possible K positions


A toggle clamp is made of two bars. The first is pinned to the bench at a fixed pin J and is 15.8 mm long, ending at a pin K. The second runs from K out to a clamping pad at L. Set up coordinates with J at the origin. The pad has to reach the point (23.5, -15.7) on the workpiece, and in that clamped position the angle at pin K, measured between the two bars, must come out at 150 degrees. The length of the second bar has not been decided yet - it has to be chosen to make that happen. The elbow at K stands above the straight line from J to the pad.

"""Toggle clamp with the second bar length to be found

Oracle formalization for mechh_t4_mechh_toggle_derived_bar_0042. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(36)

J, K, L = scene.add.points(["J", "K", "L"])

scene.constraint.eq(J.x, 0, description="datum: J is the origin, the fixed pin of the clamp (x)")
scene.constraint.eq(J.y, 0, description="datum: J is the origin, the fixed pin of the clamp (y)")
scene.constraint.eq(L.x, 23.5, description="the clamping pad has to reach this point on the workpiece (x)")
scene.constraint.eq(L.y, -15.7, description="the clamping pad has to reach this point on the workpiece (y)")
scene.constraint.eq(J.distance(K), 15.8, description="the first bar JK is 15.8 long")
scene.constraint.eq(scene.add.angle(J, K, L).value, 150, description="in the clamped position the angle at pin K, between the two bars, is 150 degrees")
scene.constraint.gt(cross(J, L, K), 0.05, description="the elbow at K stands above the straight line from J to the pad")


A toggle clamp is made of two bars. The first is pinned to the bench at a fixed pin J and is 17 mm long, ending at a pin K. The second runs from K out to a clamping pad at L. Set up coordinates with J at the origin. The pad has to reach the point (22.3, -12.4) on the workpiece, and in that clamped position the angle at pin K, measured between the two bars, must come out at 155 degrees. The length of the second bar has not been decided yet - it has to be chosen to make that happen. The elbow at K stands above the straight line from J to the pad.

"""Toggle clamp with the second bar length to be found

Oracle formalization for mechh_t4_mechh_toggle_derived_bar_0043. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(34)

J, K, L = scene.add.points(["J", "K", "L"])

scene.constraint.eq(J.x, 0, description="datum: J is the origin, the fixed pin of the clamp (x)")
scene.constraint.eq(J.y, 0, description="datum: J is the origin, the fixed pin of the clamp (y)")
scene.constraint.eq(L.x, 22.3, description="the clamping pad has to reach this point on the workpiece (x)")
scene.constraint.eq(L.y, -12.4, description="the clamping pad has to reach this point on the workpiece (y)")
scene.constraint.eq(J.distance(K), 17, description="the first bar JK is 17 long")
scene.constraint.eq(scene.add.angle(J, K, L).value, 155, description="in the clamped position the angle at pin K, between the two bars, is 155 degrees")
scene.constraint.gt(cross(J, L, K), 0.05, description="the elbow at K stands above the straight line from J to the pad")


A toggle clamp is made of two bars. The first is pinned to the bench at a fixed pin J and is 17.3 mm long, ending at a pin K. The second runs from K out to a clamping pad at L. Set up coordinates with J at the origin. The pad has to reach the point (31.3, -8.3) on the workpiece, and in that clamped position the angle at pin K, measured between the two bars, must come out at 165 degrees. The length of the second bar has not been decided yet - it has to be chosen to make that happen. The elbow at K stands above the straight line from J to the pad.

"""Toggle clamp with the second bar length to be found

Oracle formalization for mechh_t4_mechh_toggle_derived_bar_0044. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(46)

J, K, L = scene.add.points(["J", "K", "L"])

scene.constraint.eq(J.x, 0, description="datum: J is the origin, the fixed pin of the clamp (x)")
scene.constraint.eq(J.y, 0, description="datum: J is the origin, the fixed pin of the clamp (y)")
scene.constraint.eq(L.x, 31.3, description="the clamping pad has to reach this point on the workpiece (x)")
scene.constraint.eq(L.y, -8.3, description="the clamping pad has to reach this point on the workpiece (y)")
scene.constraint.eq(J.distance(K), 17.3, description="the first bar JK is 17.3 long")
scene.constraint.eq(scene.add.angle(J, K, L).value, 165, description="in the clamped position the angle at pin K, between the two bars, is 165 degrees")
scene.constraint.gt(cross(J, L, K), 0.05, description="the elbow at K stands above the straight line from J to the pad")


A toggle clamp is made of two bars. The first is pinned to the bench at a fixed pin J and is 13.8 mm long, ending at a pin K. The second runs from K out to a clamping pad at L. Set up coordinates with J at the origin. The pad has to reach the point (29.6, -12.6) on the workpiece, and in that clamped position the angle at pin K, measured between the two bars, must come out at 150 degrees. The length of the second bar has not been decided yet - it has to be chosen to make that happen. The elbow at K stands above the straight line from J to the pad.

"""Toggle clamp with the second bar length to be found

Oracle formalization for mechh_t4_mechh_toggle_derived_bar_0045. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(43)

J, K, L = scene.add.points(["J", "K", "L"])

scene.constraint.eq(J.x, 0, description="datum: J is the origin, the fixed pin of the clamp (x)")
scene.constraint.eq(J.y, 0, description="datum: J is the origin, the fixed pin of the clamp (y)")
scene.constraint.eq(L.x, 29.6, description="the clamping pad has to reach this point on the workpiece (x)")
scene.constraint.eq(L.y, -12.6, description="the clamping pad has to reach this point on the workpiece (y)")
scene.constraint.eq(J.distance(K), 13.8, description="the first bar JK is 13.8 long")
scene.constraint.eq(scene.add.angle(J, K, L).value, 150, description="in the clamped position the angle at pin K, between the two bars, is 150 degrees")
scene.constraint.gt(cross(J, L, K), 0.05, description="the elbow at K stands above the straight line from J to the pad")


A straight bar has a small block pinned at each end: one block slides along a horizontal rail, the other along a vertical rail, and the two rails cross at Z, the origin of the coordinates. A scriber is clamped to the bar somewhere along its length and stays put there as the bar moves. Neither the bar's length nor where the scriber is clamped has been recorded - both have to be recovered. The mechanism is caught in two poses. In pose 1 the blocks are Bh1 on the horizontal rail and Bv1 on the vertical rail, and the scriber is at (4.1479, 19.0814). In pose 2 the blocks are Bh2 and Bv2, and the scriber has moved to (9.2898, 10.2716). In both poses the vertical-rail block is on the upper half of its rail, and between pose 1 and pose 2 the horizontal-rail block has moved further out along its own rail.

"""Elliptic trammel with unknown bar length and scriber position

Oracle formalization for mechh_t4_mechh_trammel_two_poses_0051. Every constraint below corresponds to one
statement in the problem text; the datum constraints fix the coordinate frame
the text describes, and the inequality constraints encode the discrete choices
the text makes explicit (which side, which branch).
"""
from pygeox import GeoScene

def cross(A, B, P):
    """z-component of (B-A) x (P-A). Positive iff P lies to the LEFT of the
    directed line A->B. Used to state 'above', 'on the far side', 'anticlockwise'
    without any appeal to a picture."""
    return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x)

def dot(A, B, C, D):
    """(B-A) . (D-C). Positive iff the two directions point the same way."""
    return (B.x - A.x) * (D.x - C.x) + (B.y - A.y) * (D.y - C.y)

scene = GeoScene(43)

Z, Bh1, Bv1, T1, Bh2, Bv2, T2 = scene.add.points(["Z", "Bh1", "Bv1", "T1", "Bh2", "Bv2", "T2"])

scene.constraint.eq(Z.x, 0, description="datum: Z is the origin, where the two rails cross (x)")
scene.constraint.eq(Z.y, 0, description="datum: Z is the origin, where the two rails cross (y)")
scene.constraint.eq(Bh1.y, Z.y, description="in pose 1 the first block sits on the horizontal rail")
scene.constraint.eq(Bh2.y, Z.y, description="in pose 2 the first block sits on the horizontal rail")
scene.constraint.eq(Bv1.x, Z.x, description="in pose 1 the second block sits on the vertical rail")
scene.constraint.eq(Bv2.x, Z.x, description="in pose 2 the second block sits on the vertical rail")
scene.constraint.eq(T1.x, 4.1479, description="the scriber passes through this point in pose 1 (x)")
scene.constraint.eq(T1.y, 19.0814, description="the scriber passes through this point in pose 1 (y)")
scene.constraint.eq(T2.x, 9.2898, description="the scriber passes through this point in pose 2 (x)")
scene.constraint.eq(T2.y, 10.2716, description="the scriber passes through this point in pose 2 (y)")
scene.relate.point_lies_on(T1, scene.add.line_segment(Bh1, Bv1))
scene.relate.point_lies_on(T2, scene.add.line_segment(Bh2, Bv2))
scene.constraint.eq(Bh1.distance(Bv1), Bh2.distance(Bv2), description="the bar is rigid, so it is the same length in both poses")
scene.constraint.eq(Bh1.distance(T1), Bh2.distance(T2), description="the scriber is clamped to the bar, so it sits the same distance along it in both poses")
scene.constraint.gt(Bv1.y - Z.y, 0.05, description="both poses have the second block on the upper half of the vertical rail")
scene.constraint.gt(Bv2.y - Z.y, 0.05, description="both poses have the second block on the upper half of the vertical rail")
scene.constraint.gt(Bh2.x - Bh1.x, 0.05, description="the first block has moved outward along its rail from pose 1 to pose 2")

two quantities are unknown at once - the bar length and the scriber's distance along it - so they cannot be solved one at a time

each block lies on its own rail, so one has height 0 and the other has abscissa 0

the bar is rigid, so its length is the same in both poses; the scriber is clamped, so its distance along the bar is too

the scriber lies ON the bar between the blocks in each pose, which ties the two poses together

the vertical block is on the upper half of its rail in both poses, and the horizontal block moves outward between poses