3. Levers tikzο
Diagrams of levers can be built using tikz.
3.1. First Class levers mechanical advantageο
A First Class lever diagram is shown below.
The LaTeX:
1\documentclass[12pt, varwidth, border={20mm 5mm 5mm 20mm}]{standalone}
2\usepackage{tikz}
3\usepackage{amsmath}
4\usepackage[a4paper, portrait, margin=1cm]{geometry}
5\begin{document}
6\section*{First Class Lever mechanical advantage}
7\begin{minipage}{0.5\textwidth}
8 \begin{tikzpicture}[scale=0.7,>=stealth]
9 % First class lever
10 % rod
11 \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
12 %fulcrum
13 \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[right] {fulcrum} -- (1.0,0) -- cycle;
14 %load
15 \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
16 \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10N$};
17 %effort
18 \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = 2N$};
19
20 % Distance markers
21 \draw[<->] (1,-3.0) -- (6,-3.0) node[midway,below,align=center] {$d_E= 50cm$};
22 \draw[<->] (0,-3.1) -- (1.0,-3.1) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10cm$};
23 \end{tikzpicture}
24\end{minipage}%
25\hfill
26\begin{minipage}{0.3\textwidth}
27 \begin{align*}
28 % ma
29 m.a.&=\frac{F_L}{F_E}=\frac{10N}{2N}=5 \\\\
30 m.a.&=\frac{d_E}{d_L}=\frac{50cm}{10cm}=5
31 \end{align*}
32\end{minipage}
33\end{document}
3.2. First Class levers Fd=Fdο
A question diagram of a First Class lever is shown below with an incomplete force distance calculation.
The LaTeX:
1\documentclass[12pt, varwidth, border={5mm 5mm 5mm 5mm}]{standalone}
2\usepackage{tikz}
3\usepackage{amsmath}
4% Underlining package
5\usepackage{ulem}
6% \usepackage[a4paper, portrait, margin=1cm]{geometry}
7\begin{document}
8\section*{First Class Levers}
9 \begin{minipage}{0.65\textwidth}
10 \begin{tikzpicture}[scale=0.7,>=stealth]
11 % First class lever
12 % rod
13 \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
14 %fulcrum
15 \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[below,xshift=2mm] {fulcrum} -- (1.0,0) -- cycle;
16 %load
17 \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
18 \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10N$};
19 %effort
20 \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = \dotuline{~~~~~~~}N$};
21
22 % Distance markers
23 \draw[<->] (1.0,-2.5) -- (6,-2.5) node[midway,below,align=center] {$d_E = 50.0cm$};
24 \draw[<->] (0,-2.6) -- (1.0,-2.6) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10.0cm$};
25 \end{tikzpicture}
26\end{minipage}%
27\hfill
28\begin{minipage}{0.3\textwidth}
29 \begin{align*}
30 F_E \times d_E &= F_L \times d_L \\
31 F_E &= \frac{F_L \times d_L}{d_E} \\
32 F_E &= \frac{\dotuline{~~~~~~~} \times \dotuline{~~~~~~~}}{\dotuline{~~~~~~~}} \\
33 F_E &= \dotuline{~~~~~~~}N
34 \end{align*}
35\end{minipage}
36\end{document}
An answer diagram of a First Class lever is shown below with a completed force distance calculation.
The LaTeX:
1\documentclass[12pt, varwidth, border={5mm 5mm 5mm 5mm}]{standalone}
2\usepackage{tikz}
3\usepackage{amsmath}
4% Underlining package
5\usepackage{ulem}
6% \usepackage[a4paper, portrait, margin=1cm]{geometry}
7\begin{document}
8\section*{First Class Levers}
9 \begin{minipage}{0.65\textwidth}
10 \begin{tikzpicture}[scale=0.7,>=stealth]
11 % First class lever
12 % rod
13 \draw[fill=gray!20] (-0.25,0) rectangle (6,0.1);
14 %fulcrum
15 \draw[fill=black] (0.8,-0.5) -- (1.2,-0.5) node[below,xshift=2mm] {fulcrum} -- (1.0,0) -- cycle;
16 %load
17 \draw[fill=red] (-0.25,0.1) rectangle (0.25,0.6);
18 \draw[->,thick] (0.0,0.35) -- (0.0,-2.15) node[midway,left,yshift=-0.5cm,align=center] {Load \\\\[-3ex] $F_L = 10.0N$};
19 %effort
20 \draw[->,thick] (6,0.0) -- (6,-0.5) node[midway,right,align=center] {Effort \\\\[-3ex] $F_E = 2.0N$};
21
22 % Distance markers
23 \draw[<->] (1.0,-2.5) -- (6,-2.5) node[midway,below,align=center] {$d_E = 50.0cm$};
24 \draw[<->] (0,-2.6) -- (1.0,-2.6) node[midway,below,xshift=-0.5cm,align=left] {$d_L = 10.0cm$};
25 \end{tikzpicture}
26\end{minipage}%
27\hfill
28\begin{minipage}{0.3\textwidth}
29 \begin{align*}
30 F_E \times d_E &= F_L \times d_L \\
31 F_E &= \frac{F_L \times d_L}{d_E} \\
32 F_E &= \frac{10.0 \times 10.0}{50.0} \\
33 F_E &= 2.0N
34 \end{align*}
35\end{minipage}
36\end{document}
3.3. Booklet: First Class levers Fd=Fdο
A booklet of random first class levers can be created.
3.4. Maker filesο
The python below requires the following .tex files:
The Python code that creates a booklet of 5 lever diagrams and calculations per page is:
The python file, lever_booklet_diagram_maker.py, when run, will ask for these inputs:
Choose the lever class:
"Enter 1, 2, 3 or 4 for 1st, 2nd, 3rd class levers or random "
.Choose the numnber of questions:
"- Choose the numnber of questions: "
Choose the file name base:
"Enter the base filename to be added to the prefix lever_Bk_:"
.The filename will have β_qβ added for the question booklet and β_ansβ for the answer booklet.
1from pathlib import Path
2import subprocess
3import time
4# import magick_pdf_to_png
5import lever_functions as levf
6
7currfile_dir = Path(__file__).parent
8tex_template_path = currfile_dir / "lever_booklet_template.tex"
9texans_template_path = currfile_dir / "lever_booklet_ans_template.tex"
10tex_diagram_template_path = currfile_dir / "lever_booklet_diagram_template.tex"
11
12
13def convert_to_pdf(tex_path, currfile_dir, aux_path):
14 """
15 Converts a TeX file to PDF format using pdfLaTeX.
16
17 Args:
18 tex_path (str): The path to the TeX file.
19 currfile_dir (str): The path to the directory where the TeX file is located.
20 aux_path (str): The path to the directory where auxiliary files will be stored.
21
22 Returns:
23 subprocess.CompletedProcess: A subprocess.CompletedProcess object containing information about the completed process.
24
25 Raises:
26 FileNotFoundError: If the TeX file does not exist.
27 subprocess.CalledProcessError: If pdfLaTeX returns a non-zero exit code.
28 """
29 result = subprocess.run(
30 [
31 "pdfLaTeX",
32 tex_path,
33 "-output-directory",
34 currfile_dir,
35 "-aux-directory",
36 aux_path,
37 ],
38 stdout=subprocess.PIPE,
39 )
40
41
42# % end modify values for lever
43# tex_keys = ['ans_force_l','ans_force_e','ans_dist_l', 'ans_dist_e', 'effort_vector','fulc_c', 'fulc_l', 'fulc_r' ]
44tex_keys_q = ["force_l", "force_e", "dist_l", "dist_e", 'effort_vector','fulc_c', 'fulc_l', 'fulc_r']
45
46
47def make1_diagram(tex_diagram_template_txt, num1,):
48 tex_diagram_template_txt_ans = tex_diagram_template_txt
49 kv = levf.get_lever_dict(num1)
50 for key, value in kv.items():
51 tex_diagram_template_txt_ans = tex_diagram_template_txt_ans.replace(
52 "<<" + key + ">>", value
53 )
54 for key, value in kv.items():
55 if key in tex_keys_q:
56 tex_diagram_template_txt = tex_diagram_template_txt.replace(
57 "<<" + key + ">>", value
58 )
59 else:
60 tex_diagram_template_txt = tex_diagram_template_txt.replace(
61 "<<" + key + ">>", "\dotuline{~~~~~~~}" # non breaking spaces for gaps
62 )
63 return tex_diagram_template_txt, tex_diagram_template_txt_ans
64
65
66def main():
67 num1 = input("Enter 1, 2, 3 or 4 for 1st, 2nd, 3rd class levers or random \n")
68 if num1.strip().isdigit():
69 num1 = int(num1)
70 if num1 not in [1, 2, 3, 4]:
71 num1 = 4 # random by default
72 else:
73 num1 = 4 # random by default
74 #
75 numq = input("Enter the number of questions from 1 to 20 \n")
76 if numq.strip().isdigit():
77 numq = int(numq)
78 if not numq in range(1,21):
79 numq = 6 # random by default
80 else:
81 numq = 6 # random by default
82 #
83 filename = input("Enter the base filename to be added to the prefix lever_Bk_: \n")
84 if not filename:
85 filename = "1" # "lever_Bk_1_q and lever_Bk_1_ans as default file"
86 # set names of files that are made
87 # questions
88 tex_output_path = currfile_dir / f"lever_Bk_{filename}_q.tex"
89 pdf_path = currfile_dir / f"lever_Bk_{filename}_q.pdf"
90 aux_path = currfile_dir / "temp"
91 # answers
92 tex_output_path_ans = currfile_dir / f"lever_Bk_{filename}_ans.tex"
93 pdf_path_ans = currfile_dir / f"lever_Bk_{filename}_ans.pdf"
94
95 # Read in the LaTeX template file
96 with open(tex_template_path, "r") as infile:
97 tex_template_txt = infile.read()
98 # Read in the LaTeX template file for answers
99 with open(texans_template_path, "r") as infile:
100 tex_template_txt_ans = infile.read()
101 # Read in the LaTeX diagram template file
102 with open(tex_diagram_template_path, "r") as infile:
103 tex_diagram_template_txt = infile.read()
104
105 # Generate the <<diagram>> replacement tex
106 # diagram_text, diagram_text_ans = make1_diagram(tex_diagram_template_txt, num1)
107
108 # <<diagrams>>
109 # generate diagrams text and text for answers
110 diagrams_text = ""
111 diagrams_text_ans = ""
112 # add the headtext
113 headtext = r"\pagebreak ~ \newline ~ \newline"
114 rmax = numq + 1
115 for i in range(1, rmax):
116 img_tex, img_tex_ans = make1_diagram(tex_diagram_template_txt, num1)
117 if i > 5 and i % 5 == 1:
118 diagrams_text += headtext
119 diagrams_text_ans += headtext
120 diagrams_text += img_tex
121 diagrams_text_ans += img_tex_ans
122
123 # Replace the <<diagrams>> placeholder in the LaTeX template
124 tex_template_txt = tex_template_txt.replace("<<diagrams>>", diagrams_text)
125 tex_template_txt_ans = tex_template_txt_ans.replace("<<diagrams>>", diagrams_text_ans)
126 # Write the question diagrams tex to an output file
127 with open(tex_output_path, "w") as outfile:
128 outfile.write(tex_template_txt)
129 # Write the answer diagrams tex to an output file
130 with open(tex_output_path_ans, "w") as outfile:
131 outfile.write(tex_template_txt_ans)
132
133 # Wait for the files to be created
134 time.sleep(1)
135 # convert to pdf
136 convert_to_pdf(tex_output_path, currfile_dir, aux_path)
137 convert_to_pdf(tex_output_path_ans, currfile_dir, aux_path)
138
139 # Wait for the files to be created
140 # time.sleep(1)
141 # convert to png
142 # magick_pdf_to_png.convert_pdf_to_png(pdf_path, png_path)
143 # magick_pdf_to_png.convert_pdf_to_png(pdf_path_ans, png_path_ans)
144
145
146if __name__ == "__main__":
147 print("starting")
148 main()
149 print("finished")