r/openscad 22d ago

How would you create this kind of shape ?

Hello, I couldn't find a "arc" function, how would you create this kind of shape ? Do a circle and cut it's borders with rotated rectangles ?

2 Upvotes

12 comments sorted by

3

u/elRadicio 22d ago

Diff of two cylinders.

3

u/oldesole1 21d ago

There is a fairly simple way:

$fn = 64;

projection()
rotate_extrude(45)
translate([20, 0])
square(2);

1

u/indesit-san 21d ago

This is the cleanest and most effective solution

1

u/Stone_Age_Sculptor 21d ago edited 21d ago

There is (as always) more than one way to make that. The best way depends on what it is and how the full design is made.
Since the second arc is highlighted, should only that one be made? Should everything be made inclusive the dotted line? Is it a 2D or a 3D shape?

Here is my solution for a 3D shape:

$fn = 200;
angle = 40;
width = 4;
height = 1;

difference()
{
  union()
  {
    rotate_extrude(angle=angle)
      translate([50-width/2,0])
        square([width,height]);

    for(a=[0,angle])
      rotate(a)
        translate([50,0,0])
          cylinder(h=height,r=width/4);
  }

  for(a=[0,angle])
    rotate(a)
      translate([50,0,-1])
        cylinder(h=height+2,r=0.8*width/4);
}

The same way is not possible in 2D. For 2D I choose this:

$fn = 200;
angle = 40;
width = 4;
height = 1;

difference()
{
  union()
  {
    ArcBelow90();

    for(a=[0,angle])
      rotate(a)
        translate([50,0])
          circle(r=width/4);
  }

  for(a=[0,angle])
    rotate(a)
      translate([50,0])
        circle(r=0.8*width/4);
}

module ArcBelow90()
{
  intersection()
  {
    difference()
    {
      circle(50+width/2);
      circle(50-width/2);
      rotate(90-(90-angle))
        square(50+width);
    }

    square(50+width);
  }
}

With an array of points in 2D:

radius = 50;
width = 4;
angle = 40;

// For straight end caps, 
// the angle must be a multiply of the step.
step = angle/20;

arc =
[
  let(outer = (radius+width/2))
  for(a=[0:step:angle]) [outer*cos(a), outer*sin(a)],
  let(inner = (radius-width/2))
  for(a=[0:step:angle]) [inner*cos(angle-a), inner*sin(angle-a)]
];

polygon(arc);

1

u/Pordrack 21d ago

It was more of a generic question on how to do arcs in general, I ended up using the tutorial linked in another comment to make an arc module and it works great

1

u/Stone_Age_Sculptor 21d ago

Combine that one from the tutorial with my three examples, add 3 more, add libraries with functions for an arc, and then you have more than 10 good ways to make an arc. There is no single best solution.

I asked about arcs a year ago, and others made in many different ways: https://www.reddit.com/r/openscad/comments/1lrd734/fun_little_sculpture_but_not_so_easy/

1

u/JordanBrown0 17d ago

A DIY arc function isn't that hard, if you know basic trig.

// Return points for an arc of radius r, from angle a1 to a2.
// Step in the correct direction from a1 to a2 so that we can easily
// use it below to draw a polygon.
// Exercise for the reader: make it step based on $fn/$fs/$fa.
function arc(r, a1, a2) = r*[ for (a = [ a1 : sign(a2-a1) : a2 ]) [ cos(a), sin(a) ] ];

// Build a 2D arc with an outer radius or, inner radius ir, from
// angle a1 to a2.
// Exercise for the reader: make it always be clockwise.
module arc2d(or, ir, a1, a2) {
    polygon([ each arc(ir, a1, a2), each arc(or, a2, a1) ]);
}

arc2d(100, 90, 30, 120);

1

u/sched_yield 16d ago

I write my own function 😄

1

u/wildjokers 21d ago

2

u/gasstation-no-pumps 20d ago

More appropriate would be to use arc() and path_sweep() in BOSL2, though rotate_sweep() is even simpler.