if type(window) ~= "userdata" then window = ofWindow() end local clock = ofClock(this, "setup") local DV = class() function DV:__init(x, y) self.x = x self.y = y self.bBeingDragged = false self.bOver = false self.radius = 4 end local nCurveVertexes = 0 local curveVertices = {} function M.new() ofWindow.addListener("setup", this) ofWindow.addListener("draw", this) ofWindow.addListener("mouseMoved", this) ofWindow.addListener("mouseDragged", this) ofWindow.addListener("mousePressed", this) ofWindow.addListener("mouseReleased", this) window:setPosition(30, 100) window:setSize(1024, 768) if ofWindow.exists then clock:delay(0) else window:create() end end function M.free() window:destroy() ofWindow.removeListener("setup", this) ofWindow.removeListener("draw", this) ofWindow.removeListener("mouseMoved", this) ofWindow.removeListener("mouseDragged", this) ofWindow.removeListener("mousePressed", this) ofWindow.removeListener("mouseReleased", this) end function M.setup() ofSetWindowTitle("polygon example") ofBackground(255, 255, 255, 255) nCurveVertexes = 7 curveVertices = {DV(326, 209), DV(306, 279), DV(265, 331), DV(304, 383), DV(374, 383), DV(418, 209), DV(345, 279)} end function M.draw() ofFill() --[[--------------------------------------------------------------- draw a star use poly winding odd, the default rule --]]--------------------------------------------------------------- ofSetHexColor(0xe0be21) ofSetPolyMode(OF_POLY_WINDING_ODD) ofBeginShape() ofVertex(200, 135) ofVertex(15, 135) ofVertex(165, 25) ofVertex(105, 200) ofVertex(50, 25) ofEndShape() --[[--------------------------------------------------------------- draw a star use poly winding nonzero --]]--------------------------------------------------------------- ofSetHexColor(0xb5de10) ofSetPolyMode(OF_POLY_WINDING_NONZERO) ofBeginShape() ofVertex(400, 135) ofVertex(215, 135) ofVertex(365, 25) ofVertex(305, 200) ofVertex(250, 25) ofEndShape() --[[--------------------------------------------------------------- draw a star dynamically use the mouse position as a pct to calc nPoints and internal point radius --]]--------------------------------------------------------------- local xPct = ofGetMouseX() / ofGetWidth() local yPct = ofGetMouseY() / ofGetHeight() local nTips = 5 + xPct * 60 local nStarPts = math.min(nTips * 2, 100) local angleChangePerPt = OF_TWO_PI / nStarPts local innerRadius = 0 + yPct * 80 local outerRadius = 80 local origx = 525 local origy = 100 local angle = 0 ofSetHexColor(0xa16bca) ofBeginShape() for i = 0, nStarPts do if i % 2 == 0 then local x = origx + innerRadius * math.cos(angle) local y = origy + innerRadius * math.sin(angle) ofVertex(x, y) else local x = origx + outerRadius * math.cos(angle) local y = origy + outerRadius * math.sin(angle) ofVertex(x, y) end angle = angle + angleChangePerPt end ofEndShape() --[[--------------------------------------------------------------- poylgon of random points lots of self intersection, 500 pts is a good stress test --]]--------------------------------------------------------------- ofSetHexColor(0x0cb0b6) ofSetPolyMode(OF_POLY_WINDING_ODD) ofBeginShape() for i = 1, 10 do ofVertex(ofRandom(650, 850), ofRandom(20, 200)) end ofEndShape() --[[--------------------------------------------------------------- use sin cos and time to make some spirally shape --]]--------------------------------------------------------------- ofPushMatrix() ofTranslate(100, 300, 0) ofSetHexColor(0xff2220) ofFill() ofSetPolyMode(OF_POLY_WINDING_ODD) ofBeginShape() local angleStep = OF_TWO_PI / (100 + math.sin(ofGetElapsedTimef() / 5) * 60) local radiusAdder = 0.5 local radius = 0 for i = 1, 200 do local anglef = (i) * angleStep local x = radius * math.cos(anglef) local y = radius * math.sin(anglef) ofVertex(x, y) radius = radius + radiusAdder end ofEndShape(OF_CLOSE) ofPopMatrix() --[[--------------------------------------------------------------- ofCurveVertex because it uses catmul rom splines, we need to repeat the first and last items so the curve actually goes through those points --]]--------------------------------------------------------------- ofSetHexColor(0x2bdbe6) ofBeginShape() for i = 1, nCurveVertexes do if i == 1 then ofCurveVertex(curveVertices[1].x, curveVertices[1].y) ofCurveVertex(curveVertices[1].x, curveVertices[1].y) elseif i == nCurveVertexes then ofCurveVertex(curveVertices[i].x, curveVertices[i].y) ofCurveVertex(curveVertices[1].x, curveVertices[1].y) ofCurveVertex(curveVertices[1].x, curveVertices[1].y) else ofCurveVertex(curveVertices[i].x, curveVertices[i].y) end end ofEndShape() ofEnableAlphaBlending() ofNoFill() ofSetColor(0, 0, 0, 40) ofBeginShape() for i = 1, nCurveVertexes do ofVertex(curveVertices[i].x, curveVertices[i].y) end ofEndShape(true) ofSetColor(0, 0, 0, 80) for i = 1, nCurveVertexes do if curveVertices[i].bOver == true then ofFill() else ofNoFill() end ofDrawCircle(curveVertices[i].x, curveVertices[i].y, 4) end ofDisableAlphaBlending() --[[--------------------------------------------------------------- ofBezierVertex with ofBezierVertex we can draw a curve from the current vertex through the the next three vertexes we pass in. (two control points and the final bezier point) --]]--------------------------------------------------------------- local x0 = 500 local y0 = 300 local x1 = 550 + 50 * math.cos(ofGetElapsedTimef() * 1.0) local y1 = 300 + 100 * math.sin(ofGetElapsedTimef() / 3.5) local x2 = 600 + 30 * math.cos(ofGetElapsedTimef() * 2.0) local y2 = 300 + 100 * math.sin(ofGetElapsedTimef()) local x3 = 650 local y3 = 300 ofFill() ofSetHexColor(0xFF9933) ofBeginShape() ofVertex(x0, y0) ofBezierVertex(x1, y1, x2, y2, x3, y3) ofEndShape() ofEnableAlphaBlending() ofFill() ofSetColor(0, 0, 0, 40) ofDrawCircle(x0, y0, 4) ofDrawCircle(x1, y1, 4) ofDrawCircle(x2, y2, 4) ofDrawCircle(x3, y3, 4) ofDisableAlphaBlending() --[[--------------------------------------------------------------- holes / ofNextContour with ofNextContour we can create multi-contour shapes this allows us to draw holes, for example... --]]--------------------------------------------------------------- ofFill() ofSetHexColor(0xd3ffd3) ofDrawRectangle(80, 480, 140, 70) ofSetHexColor(0xff00ff) ofBeginShape() ofVertex(100, 500) ofVertex(180, 550) ofVertex(100, 600) ofNextContour(true) ofVertex(120, 520) ofVertex(160, 550) ofVertex(120, 580) ofEndShape(true) --[[--------------------------------------------------------------- CSG / ofNextContour with different winding rules, you can even use ofNextContour to perform constructive solid geometry --]]--------------------------------------------------------------- ofNoFill() ofPushMatrix() ofSetPolyMode(OF_POLY_WINDING_ODD) ofBeginShape() ofVertex(300, 500) ofVertex(380, 550) ofVertex(300, 600) ofNextContour(true) for i = 1, 20 do local anglef = (i / 19.0) * OF_TWO_PI local x = 340 + 30 * math.cos(anglef) local y = 550 + 30 * math.sin(anglef) ofVertex(x, y) radius = radius + radiusAdder end ofEndShape(true) ofTranslate(100, 0, 0) ofSetPolyMode(OF_POLY_WINDING_NONZERO) ofBeginShape() ofVertex(300, 500) ofVertex(380, 550) ofVertex(300, 600) ofNextContour(true) for i = 1, 20 do local anglef = (i / 19.0) * OF_TWO_PI local x = 340 + 30 * math.cos(anglef) local y = 550 + 30 * math.sin(anglef) ofVertex(x, y) radius = radius + radiusAdder end ofEndShape(true) ofTranslate(100, 0, 0) ofSetPolyMode(OF_POLY_WINDING_ABS_GEQ_TWO) ofBeginShape() ofVertex(300, 500) ofVertex(380, 550) ofVertex(300, 600) ofNextContour(true) for i = 1, 20 do local anglef = (i / 19.0) * OF_TWO_PI local x = 340 + 30 * math.cos(anglef) local y = 550 + 30 * math.sin(anglef) ofVertex(x, y) radius = radius + radiusAdder end ofEndShape(true) ofPopMatrix() ofSetHexColor(0x000000) ofDrawBitmapString("(a) star"..string.char(10).."winding rule odd", 20, 210) ofSetHexColor(0x000000) ofDrawBitmapString("(b) star"..string.char(10).."winding rule nonzero", 220, 210) ofSetHexColor(0x000000) ofDrawBitmapString("(c) dynamically"..string.char(10).."created shape", 420, 210) ofSetHexColor(0x000000) ofDrawBitmapString("(d) random points"..string.char(10).."poly", 670, 210) ofSetHexColor(0x000000) ofDrawBitmapString("(e) fun with sin/cos", 20, 410) ofSetHexColor(0x000000) ofDrawBitmapString("(f) ofCurveVertex"..string.char(10).."uses catmull rom"..string.char(10).."to make curved shapes", 220, 410) ofSetHexColor(0x000000) ofDrawBitmapString("(g) ofBezierVertex"..string.char(10).."uses bezier to draw curves", 460, 410) ofSetHexColor(0x000000) ofDrawBitmapString("(h) ofNextContour"..string.char(10).."allows for holes", 20, 610) ofSetHexColor(0x000000) ofDrawBitmapString("(i) ofNextContour"..string.char(10).."can even be used for CSG operations"..string.char(10).."such as union and intersection", 260, 620) end function M.mouseMoved(e) for i = 1, nCurveVertexes do local diffx = e.x - curveVertices[i].x local diffy = e.y - curveVertices[i].y local dist = math.sqrt(diffx * diffx + diffy * diffy) if dist < curveVertices[i].radius then curveVertices[i].bOver = true else curveVertices[i].bOver = false end end end function M.mouseDragged(e) for i = 1, nCurveVertexes do if curveVertices[i].bBeingDragged == true then curveVertices[i].x = e.x curveVertices[i].y = e.y end end end function M.mousePressed(e) for i = 1, nCurveVertexes do local diffx = e.x - curveVertices[i].x local diffy = e.y - curveVertices[i].y local dist = math.sqrt(diffx * diffx + diffy * diffy) if dist < curveVertices[i].radius then curveVertices[i].bBeingDragged = true else curveVertices[i].bBeingDragged = false end end end function M.mouseReleased(e) for i = 1, nCurveVertexes do curveVertices[i].bBeingDragged = false end end