Another Noob starting

351 views
Skip to first unread message

Andreas Zielke

unread,
Aug 17, 2021, 6:10:57 AM8/17/21
to CadQuery
Dear all,

coming from GUI-based CAD, I'm just getting started with CadQuery. 
To get started, I wanted to replicate a 2d sketch/body with the following instructions:
  • Have two circles c1, c2 with radius1, radius2 specified on the XY plane.
  • Both centers are on the positive X axis. c1 is tangential to the Y axis.
  • The distance between the centers of the circles or rather the width of the resulting body is known.
  • Connect both circles with non-intersecting lines tangent to both circles.
  • Extrude the shape.
Using a GUI based CAD I constructed the body like so:
  • Draw a construction line colinear with the X axis, starting at the origin and ending at the width of the body.
  • Draw c1 with it's center on the construction line, touching the origin. Specify radius/diameter.
  • Draw c2 with it's center on the construction line, touching the endpoint of the construction line. Specify radius/diameter.
  • Draw a line from a point on c1 to a point on c2, specify tangential constraints for the line and both c1 and c2.
  • Mirror the line along the X axis.
Clipboard01.png
(I've included some derived dimensions in the sketch above, as they might make reading my code below easier.)

Using QueryCad I calculated the coordinates of the points for the line tangential to both circles and drew an arc with the known radius1 from the origin to the first point, then the line and then a tangential arc to the X axis. Then I mirrored the wire and extruded like so:

import cadquery as cq
import math

# Parameters; assertions skipped
radius1 = 45
radius2 = 95
total_width = 350
extrusion_depth = 20

# the center for both arcs, for improved readability
center_x_arc1 = radius1
center_x_arc2 = total_width - radius2

distance_centers = center_x_arc2 - center_x_arc1

# angle between the X axis and the tangential connector
alpha = math.asin((radius2 - radius1) / distance_centers)

# coordinates of the points on both arcs where the tangential line starts/ends
x1 = center_x_arc1 - radius1 * math.sin(alpha)
y1 = radius1 * math.cos(alpha)

x2 = center_x_arc2 - radius2 * math.sin(alpha)
y2 = radius2 * math.cos(alpha)

result = cq.Workplane("XY").radiusArc((x1, y1), radius1).lineTo(x2, y2).tangentArcPoint((total_width, 0), relative=False).mirrorX().extrude(extrusion_depth)
 
My question is: Calculating the coordinates of both points appears a bit complex - do you have suggestions to improve the way the shape is constructed? 
I would be very happy if you could comment.

All the best
Andreas

Roger Maitland

unread,
Aug 17, 2021, 12:27:16 PM8/17/21
to Andreas Zielke, CadQuery
Hi Andreas,

I had a similar problem to solve when creating chains that wrapped around sprockets in my cq_warehouse package. To help with these types of problems I extended the Vector class (see here) with the addition of rotate functions (one for each axis) to do some of the calculations that you've shown in your code.  Here is an alternative implementation using my rotateZ() extension and an example of how to extend the Vector class without referring to my code:
import math
import cadquery as cq
import cq_warehouse.extensions

# Extend the Vector class with a method that returns a two dimensional point
def _toTupleTwo(self):
return (self.x, self.y)
cq.Vector.toTupleTwo = _toTupleTwo

# Parameters; assertions skipped
radii = [45, 95]
total_width = 350
extrusion_depth = 20

center_points = [cq.Vector(radii[0], 0), cq.Vector(total_width - radii[1], 0)]
distance_centers = (center_points[1] - center_points[0]).Length

# angle between the X axis and the tangential connector
alpha = math.degrees(math.asin((radii[1] - radii[0]) / distance_centers))

# calculate the points where the tangents intersect the circles
positive_y_intersect_points = [
cq.Vector(radii[i], 0).rotateZ(alpha + 90) + center_points[i] for i in range(2)
]
negative_y_intersect_points = [
cq.Vector(p.x, -p.y) for p in positive_y_intersect_points
]

result = (
cq.Workplane("XY")
.moveTo(*negative_y_intersect_points[0].toTupleTwo())
.radiusArc(positive_y_intersect_points[0], radii[0])
.lineTo(*positive_y_intersect_points[1].toTupleTwo())
.tangentArcPoint(negative_y_intersect_points[1], relative=False)
.close()
.extrude(extrusion_depth)
)
The Vector class is fundamental to CadQuery so taking a quick tour of the code will be instructive.

Cheers,
Roger

--
cadquery home: https://github.com/CadQuery/cadquery
post issues at https://github.com/CadQuery/cadquery/issues
run it at home at : https://github.com/CadQuery/CQ-editor
---
You received this message because you are subscribed to the Google Groups "CadQuery" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cadquery+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cadquery/67c982a5-1303-46e2-80b3-d71f9fce6a4an%40googlegroups.com.

Lorenz

unread,
Aug 22, 2021, 12:01:02 AM8/22/21
to CadQuery

Here is another variation, using selectors (origin at c1).

import cadquery as cq
import math

radius1 = 45
radius2 = 95
total_width = 350
extrusion_depth = 20

distance_centers = total_width - radius2 - radius1

# angle between the X axis and the tangential connector
alpha = math.degrees(math.asin((radius2 - radius1) / distance_centers))

p1 = cq.Workplane("XY").polarLine(radius1, 90 + alpha).vertices().last().val().toTuple()

p2 = (
    cq.Workplane("XY")
    .polarLine(radius2, 90 + alpha)
    .vertices()
    .last()
    .translate((distance_centers, 0, 0))
    .val()
    .toTuple()
)

result = (
    cq.Workplane("XY")
    .moveTo(-radius1, 0)
    .radiusArc(p1, radius1)
    .lineTo(*p2)
    .tangentArcPoint((distance_centers + radius2, 0), relative=False)
    .mirrorX()
)
Reply all
Reply to author
Forward
0 new messages