sketchucation logo sketchucation
    • Login
    πŸ€‘ SketchPlus 1.3 | 44 Tools for $15 until June 20th Buy Now

    Draw2d GL_POLYGON

    Scheduled Pinned Locked Moved Developers' Forum
    7 Posts 3 Posters 903 Views 3 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • J Offline
      jorat1346
      last edited by

      Hi,

      when drawing object using this:

      view.draw2d GL_POLYGON, arrayOfPoint
      

      the polygon is not drawn correctly. This link explain a bit the problem: http://www.codeproject.com/KB/openGL/OpenGL_Geometric.aspx#GL_POLYGON57

      To solve that problem, we have to implement the two-ears algorithm.

      My question is: as anyone here have already implemented that algorithm in ruby/skechup or an equivalent to solve that problem?

      Thanks
      Jo

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        Can you give an example of an polygon not drawn correctly?

        Are you referring to the likes of this?

        http://www.codeproject.com/KB/openGL/OpenGL_Geometric/OpenGL_Geometric_Primitives_26.gif

        If so - isn't that just because the points given in an order so that the lines cross? The shape would draw correct if the points had specified two triangular polygons.

        Thomas Thomassen β€” SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • J Offline
          jorat1346
          last edited by

          I'm reffering to the shape 3:

          http://www.codeproject.com/KB/openGL/OpenGL_Geometric/OpenGL_Geometric_Primitives_27.gif

          There is definitely a problem with it. The link that i'm referring to is for a bug in opengl, but the same bug appear in sketchup when using draw2d.

          1 Reply Last reply Reply Quote 0
          • thomthomT Offline
            thomthom
            last edited by

            Oh... so convex shapes will all be drawn like that? That's a bit of a bugger...

            Thomas Thomassen β€” SketchUp Monkey & Coding addict
            List of my plugins and link to the CookieWare fund

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by

              Appreciate it!
              I've not had to draw such polygons - yet. But I'm sure I'd run into it in the near future as I've been using more and more of view.draw to make tool UI.

              Thanks for the link to the original C++ - might be interesting to port into an Ruby C extension.

              Thomas Thomassen β€” SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • Chris FullmerC Offline
                Chris Fullmer
                last edited by

                Yeah, very cool. Thanks!

                Lately you've been tan, suspicious for the winter.
                All my Plugins I've written

                1 Reply Last reply Reply Quote 0
                • J Offline
                  jorat1346
                  last edited by

                  @thomthom said:

                  Oh... so convex shapes will all be drawn like that? That's a bit of a bugger...

                  In fact. 😞

                  But good news, I applied my good still in ruby (started to program in ruby last friday) to translate an algorithm that fix just that which we call polygon triangulation.

                  I converted the algorithm from c++ to ruby:
                  (Original source code: http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml)

                  # @param contour is an array of Vector2d
                  # @return area
                  def triangulateArea(contour)
                  	n = contour.length
                  	a = 0
                  	p = n - 1
                  	for q in 0...n do
                  		c1 = contour[p]
                  		c2 = contour[q]
                  		a = a + c1.x * c2.y - c2.x * c1.y
                  		p = q
                  	end
                  	return a / 2
                  end
                  
                  # Check is P is inside the triangle formed by A-B-C.
                  # @param A Point3d of the triangle
                  # @param B Point3d of the triangle
                  # @param C Point3d of the triangle
                  # @param P Point3d that have to be checked if inside A-B-C
                  # @return true if inside.
                  def triangulateInsideTriangle(ax, ay, bx, by, cx, cy, px, py)
                  	i_ax = cx - bx
                  	i_ay = cy - by
                  	i_bx = ax - cx
                  	i_by = ay - cy
                  	i_cx = bx - ax
                  	i_cy = by - ay
                  	apx = px - ax
                  	apy = py - ay
                  	bpx = px - bx
                  	bpy = py - by
                  	cpx = px - cx
                  	cpy = py - cy
                  
                  	aCROSSbp = i_ax*bpy - i_ay*bpx
                  	cCROSSap = i_cx*apy - i_cy*apx
                  	bCROSScp = i_bx*cpy - i_by*cpx
                  
                  	return aCROSSbp >= 0 && bCROSScp >= 0 && cCROSSap >= 0
                  end
                  
                  # param contour is an array of Point3d where z is not used.
                  # param u is an index  in tV
                  # param v is an index  in tV
                  # param w is an index  in tV
                  # param n is the size of tV
                  # param tV is an array in index in contour.
                  def triangulateSnip(contour, u, v, w, n, tV)
                  	ax = contour[tV[u]].x
                  	ay = contour[tV[u]].y
                  
                  	bx = contour[tV[v]].x
                  	by = contour[tV[v]].y
                  
                  	cx = contour[tV[w]].x
                  	cy = contour[tV[w]].y
                  
                  	if 0.0000000001 > (((bx-ax)*(cy-ay)) - ((by-ay)*(cx-ax)))
                  		return false
                  	end
                  
                  	for p in 0...n do
                  		if p != u && p != v && p != w
                  			px = contour[tV[p]].x
                  			py = contour[tV[p]].y
                  			if triangulateInsideTriangle(ax,ay,bx,by,cx,cy,px,py)
                  				return false
                  			end
                  		end
                  	end
                  
                  	return true
                  end
                  
                  # @param contour is an array of Point3d for a polygon
                  # @return an array of Point3d where all 3 points is a triangle which
                  #		  can be drawn with "view.draw2d GL_POLYGON, result"
                  def triangulateProcess(contour)
                  	result = Array.new
                  	
                  	n = contour.length
                  	if n < 3
                  		puts "Error; contour.length < 3"
                  		return nil
                  	end
                  
                  	# We want a counter-clockwise polygon in tV
                  	tV = Array.new
                  	if triangulateArea(contour) > 0
                  		for v in 0...n do
                  			tV << v
                  		end
                  	else
                  		for v in 0...n do
                  			tV << ((n - 1) - v)
                  		end
                  	end
                  	
                  	nv = n
                  
                  	# Remove nv-2 Vertices, creating 1 triangle every time
                  	count = 2 * nv   # Error detection
                  	
                  	m = 0
                  	v = nv - 1
                  	while nv > 2
                  		# if we loop, it is probably a non-simple polygon
                  		if count <= 0
                  			# Triangulate; ERROR - probable bad polygon!
                  			puts "ERROR - probable bad polygon! ???"
                  			return nil
                  		end
                  		count -= 1
                  
                  		# three consecutive vertices in current polygon, <u,v,w>
                  		u = v
                  		if u >= nv
                  			u = 0 # previous
                  		end
                  		v = u + 1
                  		if v >= nv
                  			v = 0 # new v
                  		end
                  		w = v + 1
                  		if w >= nv
                  			w = 0 # next
                  		end
                  
                  		if triangulateSnip(contour,u,v,w,nv,tV)
                  			# true names of the vertices
                  			a = tV[u]
                  			b = tV[v]
                  			c = tV[w]
                  
                  			# output Triangle
                  			result << contour[a]
                  			result << contour[b]
                  			result << contour[c]
                  
                  			m += 1
                  
                  			# remove v from remaining polygon
                  			s = v
                  			t = v + 1
                  			while t < nv
                  				tV[s] = tV[t]
                  				s += 1
                  				t += 1
                  			end
                  			nv -= 1
                  
                  			# resest error detection counter
                  			count = 2 * nv
                  		end
                  	end
                  	
                  	return result
                  end
                  
                  

                  How to use:
                  You have to call triangulateProcess with an array of point that compose the polygon. It will return an array of point. But, this array is formed in a way that every 3 points create a triangle and can be used directly by view.draw2d GL_TRIANGLES. Ex:

                  
                  array = [[0,20,0],[20,0,0],[30,30,0],[20,20,0]]
                  r = triangulateProcess(array)
                  if !r.nil?
                  	view.draw2d GL_TRIANGLES, r
                  end
                  

                  I hope it will be help some of you,
                  Sincerely,
                  Jo

                  EDIT: Fixed errors in the code.

                  1 Reply Last reply Reply Quote 0
                  • 1 / 1
                  • First post
                    Last post
                  Buy SketchPlus
                  Buy SUbD
                  Buy WrapR
                  Buy eBook
                  Buy Modelur
                  Buy Vertex Tools
                  Buy SketchCuisine
                  Buy FormFonts

                  Advertisement