mirror of
https://github.com/gumyr/build123d.git
synced 2025-12-05 18:20:46 -08:00
Added the Triangle Sketch object
This commit is contained in:
parent
0bdaabbb2f
commit
4f79ce745c
8 changed files with 140 additions and 2 deletions
25
docs/assets/triangle_example.svg
Normal file
25
docs/assets/triangle_example.svg
Normal file
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<svg width="93.32161mm" height="100.089999mm" viewBox="-22.456606 -27.78867 44.913212 48.170658" version="1.1" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g transform="scale(1,-1)" stroke-linecap="round">
|
||||||
|
<g fill="none" stroke="rgb(0,0,0)" stroke-width="0.043314609308420446">
|
||||||
|
<path d="M -15.0,-12.360331 L 15.0,-12.360331 L -0.0,24.720662 L -15.0,-12.360331" />
|
||||||
|
<path d="M -14.95,-18.351869 L -14.95,-14.360331 L -15.05,-14.360331 L -15.05,-20.360331 L -14.95,-20.360331 L -14.95,-18.368793 A 10.137937550497139,10.137937550497139 80.53767779197437 0,0 -12.0,-19.360331 L -12.35625,-18.410331 L -3.232503,-18.410331 L -3.232503,-18.310331 L -12.35625,-18.310331 L -12.0,-17.360331 A 10.137937550497139,10.137937550497139 -80.53767779197439 0,0 -14.95,-18.351869" />
|
||||||
|
<path d="M 15.05,-20.360331 L 15.05,-14.360331 L 14.95,-14.360331 L 14.95,-18.351869 A 10.137937550497139,10.137937550497139 -99.46232220802563 0,0 12.0,-17.360331 L 12.35625,-18.310331 L 3.232503,-18.310331 L 3.232503,-18.410331 L 12.35625,-18.410331 L 12.0,-19.360331 A 10.137937550497139,10.137937550497139 99.46232220802563 0,0 14.95,-18.368793 L 14.95,-20.360331 L 15.05,-20.360331" />
|
||||||
|
<path d="M -1.117497,-17.805326 L -0.69751,-17.805326 C -0.662613,-17.483777 -0.470742,-17.341897 -0.082503,-17.340336 C 0.288221,-17.339293 0.505095,-17.478048 0.50249,-17.730326 L 0.50249,-17.840336 Q 0.50249,-17.970332 0.407495,-18.035331 Q 0.3125,-18.100329 0.067497,-18.130326 C -0.052501,-18.146993 -0.135834,-18.15866 -0.182503,-18.165328 C -0.229172,-18.171995 -0.302507,-18.183663 -0.402507,-18.200329 C -0.502507,-18.216996 -0.572507,-18.231161 -0.612508,-18.242826 C -0.652509,-18.25449 -0.71001,-18.272823 -0.78501,-18.297823 C -0.86001,-18.322823 -0.913341,-18.348658 -0.945003,-18.375329 C -0.976666,-18.402 -1.015831,-18.436169 -1.0625,-18.477836 C -1.109169,-18.519502 -1.141669,-18.5645 -1.160002,-18.612829 C -1.194843,-18.709226 -1.234327,-18.837255 -1.232503,-18.990336 C -1.232503,-19.227 -1.155002,-19.415333 -1.0,-19.555334 C -0.844998,-19.695335 -0.635834,-19.765336 -0.37251,-19.765336 C -0.059174,-19.765336 0.237495,-19.636999 0.517497,-19.380326 Q 0.542497,-19.580326 0.644995,-19.672831 Q 0.747493,-19.765336 0.947493,-19.765336 Q 1.057503,-19.765336 1.232503,-19.720332 L 1.232503,-19.405326 Q 1.1875,-19.415336 1.142497,-19.415336 Q 0.917497,-19.415336 0.917497,-19.210323 L 0.917497,-17.670332 C 0.91906,-17.205229 0.577598,-16.953763 -0.067497,-16.955326 C -0.747499,-16.955326 -1.097499,-17.238659 -1.117497,-17.805326 M 0.50249,-18.825329 C 0.50249,-18.965325 0.429159,-19.096157 0.282495,-19.217826 C 0.135832,-19.339495 -0.052501,-19.400329 -0.282503,-19.400329 C -0.60657,-19.402413 -0.800114,-19.244909 -0.79751,-18.980326 C -0.79751,-18.846993 -0.74751,-18.742826 -0.64751,-18.667826 C -0.54751,-18.592826 -0.435843,-18.545327 -0.312508,-18.525329 C -0.189174,-18.505331 -0.04334,-18.482 0.124992,-18.455334 C 0.293324,-18.428668 0.419157,-18.395332 0.50249,-18.355326 L 0.50249,-18.825329" />
|
||||||
|
<path d="M 20.535554,-10.067153 L 16.8353,-11.56398 L 16.8728,-11.656682 L 22.434948,-9.406682 L 22.397448,-9.31398 L 20.551243,-10.060806 A 10.137937550497139,10.137937550497139 -167.43800937098342 0,0 20.364174,-6.954256 L 19.617094,-7.640759 L 14.298188,5.507928 L 14.205486,5.470428 L 19.524391,-7.678259 L 18.510124,-7.704256 A 10.137937550497139,10.137937550497139 31.486635045067814 0,0 20.535554,-10.067153" />
|
||||||
|
<path d="M 7.397448,27.767013 L 1.8353,25.517013 L 1.8728,25.42431 L 5.573054,26.921137 A 10.137937550497139,10.137937550497139 12.561990629016586 0,0 5.760124,23.814587 L 6.507204,24.50109 L 11.826109,11.352403 L 11.918812,11.389903 L 6.599906,24.53859 L 7.614174,24.564587 A 10.137937550497139,10.137937550497139 -148.51336495493217 0,0 5.588743,26.927484 L 7.434948,27.67431 L 7.397448,27.767013" />
|
||||||
|
<path d="M 11.759026,6.638225 L 15.138034,8.005102 L 14.997409,8.352736 L 14.686862,8.227113 Q 14.993397,8.669339 14.792774,9.165291 Q 14.597773,9.647347 14.117661,9.787537 Q 13.637548,9.927727 13.034982,9.683977 Q 12.446328,9.445854 12.215825,9.028995 Q 11.985323,8.612137 12.180324,8.130081 Q 12.377199,7.643393 12.88269,7.540446 L 11.603398,7.022947 L 11.759026,6.638225 M 12.571869,8.202174 Q 12.440619,8.526633 12.622372,8.823985 Q 12.804125,9.121337 13.23983,9.297588 Q 13.652359,9.464464 13.989295,9.371533 Q 14.32623,9.278603 14.453726,8.963423 Q 14.577475,8.657508 14.395227,8.368041 Q 14.212979,8.078574 13.786546,7.906074 Q 13.360113,7.733573 13.027866,7.814916 Q 12.695618,7.896259 12.571869,8.202174" />
|
||||||
|
<path d="M -5.573054,26.921137 L -1.8728,25.42431 L -1.8353,25.517013 L -7.397448,27.767013 L -7.434948,27.67431 L -5.588743,26.927484 A 10.137937550497139,10.137937550497139 -31.48663504506779 0,0 -7.614174,24.564587 L -6.599906,24.53859 L -11.940376,11.336596 L -11.847673,11.299096 L -6.507204,24.50109 L -5.760124,23.814587 A 10.137937550497139,10.137937550497139 167.43800937098345 0,0 -5.573054,26.921137" />
|
||||||
|
<path d="M -22.434948,-9.406682 L -16.8728,-11.656682 L -16.8353,-11.56398 L -20.535554,-10.067153 A 10.137937550497139,10.137937550497139 148.51336495493223 0,0 -18.510124,-7.704256 L -19.524391,-7.678259 L -14.183922,5.523735 L -14.276625,5.561235 L -19.617094,-7.640759 L -20.364174,-6.954256 A 10.137937550497139,10.137937550497139 -12.561990629016547 0,0 -20.551243,-10.060806 L -22.397448,-9.31398 L -22.434948,-9.406682" />
|
||||||
|
<path d="M -12.894355,7.644942 L -13.051856,7.255589 Q -12.607676,7.113657 -12.278364,7.274397 Q -11.949051,7.435137 -11.778428,7.85693 Q -11.579673,8.348265 -11.82215,8.788842 Q -12.064626,9.229419 -12.667193,9.473169 Q -13.255862,9.711297 -13.718368,9.56129 Q -14.180874,9.411283 -14.381496,8.915331 Q -14.557748,8.479626 -14.414766,8.11974 Q -14.271784,7.759854 -13.841811,7.542784 L -13.68431,7.932137 C -14.047409,8.154526 -14.162085,8.431038 -14.028336,8.761673 C -13.942086,8.97489 -13.792698,9.108632 -13.580174,9.162898 C -13.36765,9.217163 -13.117697,9.18617 -12.830315,9.069919 C -12.527493,8.947421 -12.314396,8.792 -12.191023,8.603654 C -12.067651,8.415308 -12.048464,8.216075 -12.133461,8.005956 C -12.260755,7.685726 -12.537162,7.555721 -12.894355,7.644942" />
|
||||||
|
<path d="M -7.301752,-9.425695 Q -7.006749,-9.140693 -7.006749,-8.67069 Q -7.006749,-8.340693 -7.164252,-8.130692 Q -7.321755,-7.92069 -7.671755,-7.785696 Q -7.166759,-7.550703 -7.166759,-6.990693 Q -7.166759,-6.835696 -7.216759,-6.688195 Q -7.266759,-6.540693 -7.379259,-6.393192 Q -7.491759,-6.24569 -7.716759,-6.155692 Q -7.941759,-6.065693 -8.246755,-6.065693 L -9.726752,-6.065693 L -9.726752,-9.710696 L -8.081749,-9.710696 Q -7.596755,-9.710696 -7.301752,-9.425695 M -7.631749,-7.0557 Q -7.631749,-7.635696 -8.361746,-7.635696 L -9.261746,-7.635696 L -9.261746,-6.475703 L -8.361746,-6.475703 Q -7.631749,-6.475703 -7.631749,-7.0557 M -8.126752,-9.300703 L -9.261746,-9.300703 L -9.261746,-8.04569 L -8.126752,-8.04569 Q -7.811746,-8.04569 -7.64175,-8.218192 Q -7.471755,-8.390693 -7.471755,-8.675703 Q -7.471755,-8.825703 -7.521755,-8.9557 Q -7.571755,-9.085696 -7.726752,-9.1932 Q -7.881749,-9.300703 -8.126752,-9.300703" />
|
||||||
|
<path d="M 6.836746,-7.40819 Q 6.794249,-7.653193 6.794249,-7.903193 Q 6.794249,-8.148196 6.836746,-8.388195 Q 6.879242,-8.628193 6.996747,-8.890693 Q 7.114252,-9.153193 7.29175,-9.348188 Q 7.469249,-9.543183 7.76675,-9.67069 Q 8.064252,-9.798196 8.439252,-9.798196 Q 9.774246,-9.798196 9.939252,-8.353193 L 9.459255,-8.353193 Q 9.374246,-8.88319 9.134247,-9.135688 Q 8.894249,-9.388187 8.444249,-9.388187 Q 7.899246,-9.388187 7.57925,-8.985688 Q 7.259255,-8.58319 7.259255,-7.898196 Q 7.259255,-7.198196 7.56675,-6.793192 Q 7.874246,-6.388187 8.404242,-6.388187 Q 8.839252,-6.388187 9.074254,-6.58319 Q 9.309255,-6.778193 9.389252,-7.168183 L 9.864252,-7.168183 Q 9.649246,-5.978193 8.459255,-5.978193 Q 8.079242,-5.978193 7.776744,-6.10819 Q 7.474246,-6.238187 7.296747,-6.435688 Q 7.119249,-6.63319 6.999246,-6.898188 Q 6.879242,-7.163187 6.836746,-7.40819" />
|
||||||
|
<path d="M 0.694995,15.993163 L 1.069995,14.89816 L 1.589998,14.89816 L 0.310002,18.543163 L -0.289998,18.543163 L -1.589998,14.89816 L -1.094995,14.89816 L -0.710002,15.993163 L 0.694995,15.993163 M 0.564998,16.383153 L -0.594995,16.383153 L 0.005005,18.043163 L 0.564998,16.383153" />
|
||||||
|
</g>
|
||||||
|
<g fill="none" stroke="rgb(0,0,0)" stroke-width="0.043314609308420446" id="dashed" stroke-dasharray="0.550096 0.275048">
|
||||||
|
<path d="M -10.0,-12.360331 A 5.0,5.0 0.0 0,1 -13.125,-7.725207" />
|
||||||
|
<path d="M 13.125,-7.725207 A 5.0,5.0 0.0 0,1 10.0,-12.360331" />
|
||||||
|
<path d="M -1.875,20.085538 A 5.0,5.0 0.0 0,1 1.875,20.085538" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.5 KiB |
|
|
@ -131,7 +131,7 @@ A procedure for avoiding this issue is to install in a conda environment, which
|
||||||
conda create -n <YOUR ENVIRONMENT NAME> python=3.10
|
conda create -n <YOUR ENVIRONMENT NAME> python=3.10
|
||||||
conda activate <YOUR ENVIRONMENT NAME>
|
conda activate <YOUR ENVIRONMENT NAME>
|
||||||
conda install -c cadquery -c conda-forge cadquery=master
|
conda install -c cadquery -c conda-forge cadquery=master
|
||||||
pip install svgwrite svgpathtools anytree scipy ipython \
|
pip install svgwrite svgpathtools anytree scipy ipython trianglesolver \
|
||||||
ocp_tessellate webcolors==1.12 numpy numpy-quaternion cachetools==5.2.0 \
|
ocp_tessellate webcolors==1.12 numpy numpy-quaternion cachetools==5.2.0 \
|
||||||
ocp_vscode requests orjson urllib3 certifi numpy-stl git+https://github.com/jdegenstein/py-lib3mf \
|
ocp_vscode requests orjson urllib3 certifi numpy-stl git+https://github.com/jdegenstein/py-lib3mf \
|
||||||
"svgpathtools>=1.5.1,<2" "svgelements>=1.9.1,<2"
|
"svgpathtools>=1.5.1,<2" "svgelements>=1.9.1,<2"
|
||||||
|
|
|
||||||
|
|
@ -329,6 +329,12 @@ Reference
|
||||||
+++
|
+++
|
||||||
Trapezoid defined by width, height and interior angles
|
Trapezoid defined by width, height and interior angles
|
||||||
|
|
||||||
|
.. grid-item-card:: :class:`~objects_sketch.Triangle`
|
||||||
|
|
||||||
|
.. image:: assets/triangle_example.svg
|
||||||
|
|
||||||
|
+++
|
||||||
|
Triangle defined by one side & two other sides or interior angles
|
||||||
|
|
||||||
|
|
||||||
Reference
|
Reference
|
||||||
|
|
@ -353,6 +359,7 @@ Reference
|
||||||
.. autoclass:: drafting.TechnicalDrawing
|
.. autoclass:: drafting.TechnicalDrawing
|
||||||
.. autoclass:: Text
|
.. autoclass:: Text
|
||||||
.. autoclass:: Trapezoid
|
.. autoclass:: Trapezoid
|
||||||
|
.. autoclass:: Triangle
|
||||||
|
|
||||||
3D Objects
|
3D Objects
|
||||||
----------
|
----------
|
||||||
|
|
|
||||||
|
|
@ -193,6 +193,32 @@ exporter.add_shape(visible, layer="Visible")
|
||||||
exporter.add_shape(hidden, layer="Hidden")
|
exporter.add_shape(hidden, layer="Hidden")
|
||||||
exporter.write(f"assets/controller.svg")
|
exporter.write(f"assets/controller.svg")
|
||||||
|
|
||||||
|
d = Draft(line_width=0.1)
|
||||||
|
# [Ex. 15]
|
||||||
|
with BuildSketch() as isosceles_triangle:
|
||||||
|
t = Triangle(a=30, b=40, c=40)
|
||||||
|
# [Ex. 15]
|
||||||
|
ExtensionLine(t.edges().sort_by(Axis.Y)[0], 6, d, label="a")
|
||||||
|
ExtensionLine(t.edges().sort_by(Axis.X)[-1], 6, d, label="b")
|
||||||
|
ExtensionLine(t.edges().sort_by(SortBy.LENGTH)[-1], 6, d, label="c")
|
||||||
|
a1 = CenterArc(t.vertices().group_by(Axis.Y)[0].sort_by(Axis.X)[0], 5, 0, t.B)
|
||||||
|
a2 = CenterArc(t.vertices().group_by(Axis.Y)[0].sort_by(Axis.X)[-1], 5, 180 - t.C, t.C)
|
||||||
|
a3 = CenterArc(t.vertices().sort_by(Axis.Y)[-1], 5, 270 - t.A / 2, t.A)
|
||||||
|
p1 = CenterArc(t.vertices().group_by(Axis.Y)[0].sort_by(Axis.X)[0], 8, 0, t.B)
|
||||||
|
p2 = CenterArc(t.vertices().group_by(Axis.Y)[0].sort_by(Axis.X)[-1], 8, 180 - t.C, t.C)
|
||||||
|
p3 = CenterArc(t.vertices().sort_by(Axis.Y)[-1], 8, 270 - t.A / 2, t.A)
|
||||||
|
t1 = Text("B", font_size=d.font_size).moved(Pos(p1 @ 0.5))
|
||||||
|
t2 = Text("C", font_size=d.font_size).moved(Pos(p2 @ 0.5))
|
||||||
|
t3 = Text("A", font_size=d.font_size).moved(Pos(p3 @ 0.5))
|
||||||
|
|
||||||
|
s = 100 / max(*isosceles_triangle.sketch.bounding_box().size)
|
||||||
|
svg = ExportSVG(scale=s)
|
||||||
|
svg.add_layer("dashed", line_type=LineType.DASHED)
|
||||||
|
svg.add_shape([a1, a2, a3], "dashed")
|
||||||
|
svg.add_shape(isosceles_triangle.sketch)
|
||||||
|
svg.add_shape([t1, t2, t3])
|
||||||
|
svg.write("assets/triangle_example.svg")
|
||||||
|
|
||||||
|
|
||||||
# [Align]
|
# [Align]
|
||||||
with BuildSketch() as align:
|
with BuildSketch() as align:
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,7 @@ dependencies = [
|
||||||
"ipython >= 8.0.0, <9",
|
"ipython >= 8.0.0, <9",
|
||||||
"py-lib3mf",
|
"py-lib3mf",
|
||||||
"ocpsvg",
|
"ocpsvg",
|
||||||
|
"trianglesolver"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.urls]
|
[project.urls]
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,7 @@ __all__ = [
|
||||||
"Text",
|
"Text",
|
||||||
"TechnicalDrawing",
|
"TechnicalDrawing",
|
||||||
"Trapezoid",
|
"Trapezoid",
|
||||||
|
"Triangle",
|
||||||
# 3D Part Objects
|
# 3D Part Objects
|
||||||
"BasePartObject",
|
"BasePartObject",
|
||||||
"CounterBoreHole",
|
"CounterBoreHole",
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,9 @@ license:
|
||||||
"""
|
"""
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
from math import cos, pi, radians, sin, tan
|
import trianglesolver
|
||||||
|
|
||||||
|
from math import cos, degrees, pi, radians, sin, tan
|
||||||
from typing import Iterable, Union
|
from typing import Iterable, Union
|
||||||
|
|
||||||
from build123d.build_common import LocationList, flatten_sequence, validate_inputs
|
from build123d.build_common import LocationList, flatten_sequence, validate_inputs
|
||||||
|
|
@ -629,3 +631,68 @@ class Trapezoid(BaseSketchObject):
|
||||||
pts.append(pts[0])
|
pts.append(pts[0])
|
||||||
face = Face.make_from_wires(Wire.make_polygon(pts))
|
face = Face.make_from_wires(Wire.make_polygon(pts))
|
||||||
super().__init__(face, rotation, self.align, mode)
|
super().__init__(face, rotation, self.align, mode)
|
||||||
|
|
||||||
|
|
||||||
|
class Triangle(BaseSketchObject):
|
||||||
|
"""Sketch Object: Triangle
|
||||||
|
|
||||||
|
Add any triangle to the sketch by specifying the length of any side and any
|
||||||
|
two other side lengths or interior angles. Note that the interior angles are
|
||||||
|
opposite the side with the same designation (i.e. side 'a' is opposite angle 'A').
|
||||||
|
|
||||||
|
Args:
|
||||||
|
a (float, optional): side 'a' length. Defaults to None.
|
||||||
|
b (float, optional): side 'b' length. Defaults to None.
|
||||||
|
c (float, optional): side 'c' length. Defaults to None.
|
||||||
|
A (float, optional): interior angle 'A' in degrees. Defaults to None.
|
||||||
|
B (float, optional): interior angle 'B' in degrees. Defaults to None.
|
||||||
|
C (float, optional): interior angle 'C' in degrees. Defaults to None.
|
||||||
|
rotation (float, optional): angles to rotate objects. Defaults to 0.
|
||||||
|
align (Union[Align, tuple[Align, Align]], optional): align min, center, or max of object.
|
||||||
|
Defaults to None.
|
||||||
|
mode (Mode, optional): combination mode. Defaults to Mode.ADD.
|
||||||
|
|
||||||
|
Raises:
|
||||||
|
ValueError: One length and two other values were not provided
|
||||||
|
"""
|
||||||
|
|
||||||
|
_applies_to = [BuildSketch._tag]
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
*,
|
||||||
|
a: float = None,
|
||||||
|
b: float = None,
|
||||||
|
c: float = None,
|
||||||
|
A: float = None,
|
||||||
|
B: float = None,
|
||||||
|
C: float = None,
|
||||||
|
align: Union[None, Align, tuple[Align, Align]] = None,
|
||||||
|
rotation: float = 0,
|
||||||
|
mode: Mode = Mode.ADD,
|
||||||
|
):
|
||||||
|
context = BuildSketch._get_context(self)
|
||||||
|
validate_inputs(context, self)
|
||||||
|
|
||||||
|
if [v is None for v in [a, b, c]].count(True) == 3 or [
|
||||||
|
v is None for v in [a, b, c, A, B, C]
|
||||||
|
].count(True) != 3:
|
||||||
|
raise ValueError("One length and two other values must be provided")
|
||||||
|
|
||||||
|
A, B, C = (radians(angle) if angle is not None else None for angle in [A, B, C])
|
||||||
|
a, b, c, A, B, C = trianglesolver.solve(a, b, c, A, B, C)
|
||||||
|
self.a = a #: length of side 'a'
|
||||||
|
self.b = b #: length of side 'b'
|
||||||
|
self.c = c #: length of side 'c'
|
||||||
|
self.A = degrees(A) #: interior angle 'A' in degrees
|
||||||
|
self.B = degrees(B) #: interior angle 'B' in degrees
|
||||||
|
self.C = degrees(C) #: interior angle 'C' in degrees
|
||||||
|
triangle = Face.make_from_wires(
|
||||||
|
Wire.make_polygon(
|
||||||
|
[Vector(0, 0), Vector(a, 0), Vector(c, 0).rotate(Axis.Z, self.B)]
|
||||||
|
)
|
||||||
|
)
|
||||||
|
center_of_geometry = sum(Vector(v) for v in triangle.vertices()) / 3
|
||||||
|
triangle.move(Location(-center_of_geometry))
|
||||||
|
alignment = None if align is None else tuplify(align, 2)
|
||||||
|
super().__init__(obj=triangle, rotation=rotation, align=alignment, mode=mode)
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,17 @@ class TestBuildSketchObjects(unittest.TestCase):
|
||||||
with BuildSketch() as test:
|
with BuildSketch() as test:
|
||||||
Trapezoid(6, 2, 30)
|
Trapezoid(6, 2, 30)
|
||||||
|
|
||||||
|
def test_triangle(self):
|
||||||
|
tri = Triangle(a=3, b=4, c=5)
|
||||||
|
self.assertAlmostEqual(tri.area, (3 * 4) / 2, 5)
|
||||||
|
tri = Triangle(c=5, C=90, a=3)
|
||||||
|
self.assertAlmostEqual(tri.area, (3 * 4) / 2, 5)
|
||||||
|
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
Triangle(A=90, B=45, C=45)
|
||||||
|
with self.assertRaises(AssertionError):
|
||||||
|
Triangle(a=10, b=4, c=4)
|
||||||
|
|
||||||
def test_offset(self):
|
def test_offset(self):
|
||||||
"""Test normal and error cases"""
|
"""Test normal and error cases"""
|
||||||
with BuildSketch() as test:
|
with BuildSketch() as test:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue