Search code examples
rubyalgorithm3dsketchup

Algorithm for discretizing a surface


My problem at hand is:

I have an arbitrarily shaped surface in Sketchup and want to check which part of the surface is in shade and which part is exposed to the sun.

My approach is to create points on the surface and subsequently check whether there are any obstructions between each point and the current position of the sun. I should add that I will need to know which points will be in shade and which points in direct sun, i.e. knowing that 30% of the surface is shaded is not sufficient for what I want to do.

  1. Does anyone know enough about Sketchup's Ruby API to tell me how to create the points? I found the PolygonMesh object which might be useful for me but couldn't get it to work.

  2. In lieu of that, what general algorithms could/should I read up on which could create the points?

  3. Is there a better approach in Sketchup or in general that could achieve what I want?

Many Thanks


Solution

  • I made some progress!

    One option is to create a point at the center of mass. For what I call regular polygons, i.e. where the vertices are evenly distributed (e.g. triangle or rectangle), the coordinates for the center of mass are

    x_com = average(vertices.x)
    y_com = average(vertices.y)
    z_com = average(vertices.z)
    

    See here for more details: http://www.mathworks.com/matlabcentral/newsreader/view_thread/22176

    This would allow to create a construction point at the center of mass, like this:

    # Find the centre of mass of a polygon based on the average of the x, y, z values.
    # A construction point is added to the centre of mass
    
    def centreofmass(aface)
        mod = Sketchup.active_model # Open model
        ent = mod.entities # All entities in model
        vert = aface.vertices
        n = 0
        x = 0
        y = 0
        z = 0
    
        vert.each{|i|
        n += 1
        x += i.position[0]
        y += i.position[1]
        z += i.position[2]
        }
    
        pt =  Geom::Point3d.new(x/n,y/n,z/n)
        c = ent.add_cpoint pt
    end
    

    From there I probably could create triangles by drawing lines from the center of mass to the original vertices. Then repeating the process for the new triangles.

    This could work for most somewhat regular shaped surfaces. I believe that there might be issues with polygons that have more vertices one side than the other, and also irregular shaped polygons, e.g. slim L shaped surfaces.

    Anyway, it looks like I got a starting point.