Monday, July 22, 2013

Something new

Picked back up on an old project namely working a bitmap conversion to curve outlining an rendered object.  As in a previous post on the subject matter, I wanted to be able to render a 2 dimensional profile to 3 dimensions here using bitmap renderings...no not for general purposed applications but mostly for things like rendering architectural exterior objects.  Best works I'd guess for 2 dimensional planar profile surfaces, that could be simply extruded once smooth curve approximation mapping has taken place.   To this a bit of supplementation, a previous post mentioned affine and rotating coordinates for simplifying the problem at hand.  In this case for curve approximation, I've chosen the Bezier curve which seems simple enough to work with.  At the moment I haven't provided any sophisticated analysis into curve fitting in as much as leaving it to the user for inputting a relative local maximum on the rotated coordinate plane where the curve is constructed without inflection points...keeping in mind over longer curve segments you could achieve the same sort of curve construction containing inflections by approximating in segments whose endpoints are the inflection points themselves if necessary (or whose segment limits such point and represented instead as a local maximum on the rotated coordinate system), for instance which should in theory lead to the same thing.  I managed to incorporate a local relative max y solution in of two simultaneous equation sets (the other were simply a neighborhood left approach slope equation), and then solved the equation sets through substitution.  The next part of this problem, since I were using a total of 4 control points for a 3rd degree bezier polynomial involved here were computing the 3rd unknown control point by solving two simultaneous sets of linear equations, one being the right neighborhood slope approach value at the 4th control point and the other being the linear slope value from control points 2 and 3 which were held constant on the transformed local y. Basically a two lines point intersection problem where assumed either lines were neither parallel relative one another.  Once control points are inputted, curve approximation takes places on the parametric segment t in the set [0,1]...leaving the user whatever t step increment for points generated along the curve.  I would have left to it blender to do the actual bezier curve constructions, but technically I'd still need to sift through for points generating on the curves and secondly, I'd rather work with mesh objects for extrusions, and I found the experience of programming bezier curves stimulating enough.  

My bezier function looked like this:
Haven't tested it as of yet...

        def kpermofn(self, n, k):
                numer = math.factorial(n)
                dena = math.factorial((n-k))
                denb = math.factorial(k)
                return (numer/(dena*denb))
        def bezier(self, n, P, tstep):
                def bernbasis(t,i,n):
                        niperm = self.kpermofn(n,i)
                        ti = math.pow(t,i)
                        neti = math.pow((1-t),(n-i))
                        return niperm*ti*neti
                Bpoints = []        
                cn = range(0,n)
                t = 0
                while t < (1 + tstep):
                        Bt = 0,0
                        for i in cn:
                              bbcoef = bernbasis(t, i, n)
                              Btx, Bty = Bt
                              Pix, Piy = P[i]
                              Bt = ((bbcoef*Pix) + Btx, (bbcoef*Piy) + Bty)
                        Bpoints.append[Bt]
                        t += tstep
                        if t > 1:
                                break

Computation of control points looks like this

        def findcpts(self, p0s, p3s, relmy):
                #p0s and p3s are defined by a two tuple coordinate pair
                #here one pair represents the linear slope values defined
                #at the neighborhood of point p0 and p3 respectively,
                #and another coordinate value defined by position of the points
                #p0 and p3.
                
                #compute relative p1y, p2y
                #here using affine and rotation of coordinate systems
                #,one can compute the relative position of y from
                #a user input relative relative maximal y assuming
                #no inflection point for a 3rd order bezier poly.
                #In the computation I've restricted the weighting
                #of relative p1y and p2y such that relp1y = relp2y
                #meaning they are equidistant from the zero on the
                #rotated coordinate plane.

                #formulation for maximal y at t=.5 is given by
                #rel y (t =.5) = 3/4(-(p1x - p0x)Sin(theta p0,p3)
                #+(p1y - p0y)cos(theta p0,p3))
                #where theta p0,p3 is the angle described between
                #control points p0 and p3
                #for more information on this derivation see my
                #site at http://lotsofexpression.blogspot.com/2012/08/exploration-of-bezier-curve.html

                #we compute theta p0, p3
                p0neighbor, p0 = p0s 
                p3neighbor, p3 = p3s
                p0x, p0y = p0
                p3x, p3y = p3
                
                hyp = self.distance(p0, p3)
                #compute adj distance
                adj = self.adj(p0,p3)
                relyslope = adj/hyp
                thetap0p3 = math.acos(adj/hyp) #in radians
                #Since there will be two unknowns in the equation
                #above will simultaneously solve using the left slope
                #approach to the neighborhood of p0...this is the
                #linear slope equation defined by p0, p1
                #py1 -py0 /px1 - px0 = p0nleftappr
                #implies py1 = p0nleftappr(px1 -px0) + py0
                #thus in the equation above solving for p1x we have
                #rely = 3/4(-(p1x - p0x) Sin(theta p0,p3) + (p0nleftappr(px1 - px0))
                #*Cos(theta p0,p3)
                # implies rely = 3/4(px1 - p0x)(p0nleftappr * Cos(theta p0,p3) -
                # Sin(theta p0,p3))
                p0nleftappr, p0nrightappr = p0neighbor
                p3nleftappr, p3nrightappr = p3neighbor
                righteval = p0nleftappr * math.cos(thetap0p3) - math.sin(thetap0p3)
                p1x = 4/3 * relmy *math.pow(righteval, -1) + p0x
                p1y = p0nleftappr*(p1x - p0x) + p0y
                #we'll use the intersection of lines formulation for solution
                #on the second control point
                p2x = (relyslope *(p1x) - p1y - p3nrightappr *(p3x) + p3y)/ (relyslope - p3nrightappr)
                p2y = relyslope*(p2x - p1x) + p1y
                cPoints = [(p0,(p1x,p1y),(p2x,p2y),p3]
                return cPoints

No comments:

Post a Comment

Oblivion

 Between the fascination of an upcoming pandemic ridden college football season, Taylor Swift, and Kim Kardashian, wildfires, crazier weathe...