How to find a circle vertices without creating it?

Hi,
I needed circle vertices and used the following code.

              cir = Sketchup.active_model.entities.add_circle cp, v1, (rad)
              cir.each { |cp| pts << cp.vertices[0].position.to_a }
              cir.each { |cp| cp.erase! }

My problem is I use code in onLButtonDown and the circle appears in Undo. Is there any way I got circle vertices without drawing it?
Your help will be highly appreciated.

Hi,

If I was you, I would probably calculate them using sin and cosin.
For example if you want 8 points around a defined point:

def circle_points(pt)
  out_points=[]
  radius=10
  angle=0
  8.times{
    px=pt[0]+radius*Math.cos(angle.degrees)
    py=pt[1]+radius*Math.sin(angle.degrees)
    out_points<<Geom::3dPoint.new(px,py,pt[2])
    angle+=45
  }
end

point=Geom::3dPoint.new(10,20,30)
round_points=circle_points(point)

Of course change the interval and number of times if you need more samples.
Best regards

direct calculating can be difficult. I calculate circle points in x y sheet and origin then move and rotate points. It works well.

              teta = 2 * Math::PI / 16
              for i in 0...17
                x1 = rad * Math::cos(i * teta)
                y1 = rad * Math::sin(i * teta)
                pts << [x1, y1, 0]
              end
              angle = vec.angle_between [0, 0, 1]
              vec2 = vec * [0, 0, 1]
              vec2 = [1, 0, 0] if vec2.length < 0.001
              tr = Geom::Transformation.new cp
              tr_rt = Geom::Transformation.rotation [0, 0, 0], vec2, -angle
              pts[@st].each{ |p| p = p.transform! tr * tr_rt }

FYI: You don’t need to use a block iterator to get an array of points.
You can get the virtual curve object from the first edge, then get the array
of it’s vertices and map them to position points:

pts = cir_edges.first.curve.vertices.map(&:position)

Whenever you need to erase multiple elements, do not use #erase! within an iterator block.
Instead use the bulk erase method:

entities.erase_entities(cir_edges)
1 Like

The title indicates you don’t want to create a circle. We can usually make use of the Sketchup API to avoid having to use sin() and cos():

  number_of_edge_curves = 16
  theta = 2.0 * Math::PI / number_of_edge_curves
  rot_tr = Geom::Transformation.rotation( ORIGIN, Z_AXIS, theta )
  point = Geom::Point3d.new( 1.0, 0.0, 0.0 ) # pts[0] with radius of unity
  pts = Array.new
  number_of_edge_curves.times do
    pts << point.clone
    point.transform!( rot_tr )
  end
  ...
  translate = Geom::Transformation.new cp
  tr_rt = Geom::Transformation.rotation ORIGIN, vec2, -angle
  scaling = Geom::Transformation.scaling( ORIGIN, scale_factor )
  pts.map!{|point| point.transform( translate * tr_rt * scaling) }

Note: Although you have 16 segments for the circle, the default is 24.

The last time through the loop results in a final point being calculated that is never used. It should rotate the point at or near the initial starting point, which is already in the first array element. Instead of setting the points based on a radius, I set it to unity, and the radius can be used as a scale factor.

Notice use of the “map!” method instead of “each”.

1 Like

Thank you for your information. I have some questions to learn more from you.

May I ask the reason? Don’t you think at end of the day SU will use SIN and COS for rotation?

I use points in view.draw_polyline and the last point should be the same as the first point to have a complete circle. I saved the code.

May I ask the reason?

1 Like

For myself, SIN and COS are more error prone. You said:

I agree. You asked:

I don’t have access to the Sketchup code, but I would think that SIN and COS would be limited to the “.rotation” constructor. After that, it should be matrix multiplication.

Yes, I wasn’t actually trying to create a circle entity. In which case, you could do a final assignment after the for loop:

pts << pts.first.clone

You also asked:

(Referring to use of the map! method). Just to make sure others who read this someday will know I accomplished the same thing in a slightly different manner. Ruby allows the same thing to be accomplished in different ways. If the code isn’t clearer to you when using map, then each may be better for yourself.