void MyPrimitive::GenerateCylinder(float a_fRadius, float a_fHeight, int a_nSubdivisions, vector3 a_v3Color) { if (a_nSubdivisions < 3) a_nSubdivisions = 3; if (a_nSubdivisions > 360) a_nSubdivisions = 360; Release(); Init(); //Your code starts here vector3 topMid(0.00f, a_fHeight / 2, 0.00f); //mid-top vertex vector3 baseMid(0.00f, -(a_fHeight / 2), 0.00f); //mid-base vertex std::vector<vector3> topPoints; //top vertices std::vector<vector3> basePoints; //base vertices for (int x = 0; x < a_nSubdivisions; x++) { //calculate vertex positions float angle = ((2 * PI) / a_nSubdivisions) * x; float x_Value = a_fRadius * sin(angle); float z_Value = a_fRadius * cos(angle); basePoints.push_back(vector3(x_Value, -(a_fHeight / 2), z_Value)); } for (int x = 0; x < a_nSubdivisions; x++) { //calculate vertex positions float angle = ((2 * PI) / a_nSubdivisions) * x; float x_Value = a_fRadius * sin(angle); float z_Value = a_fRadius * cos(angle); topPoints.push_back(vector3(x_Value, a_fHeight / 2, z_Value)); } //create base for (int x = 0; x < basePoints.size(); x++) { AddVertexPosition(baseMid); if (x == basePoints.size() - 1) { AddVertexPosition(basePoints[0]); } else { AddVertexPosition(basePoints[x + 1]); } AddVertexPosition(basePoints[x]); } //create top for (int x = 0; x <topPoints.size(); x++) { AddVertexPosition(topMid); AddVertexPosition(topPoints[x]); if (x == topPoints.size() - 1) { AddVertexPosition(topPoints[0]); } else { AddVertexPosition(topPoints[x + 1]); } } //create sides for (int x = 0; x < basePoints.size(); x++) { if (x != basePoints.size() - 1) { AddQuad(basePoints[x], basePoints[x + 1], topPoints[x], topPoints[x + 1]); } else { AddQuad(basePoints[x], basePoints[0], topPoints[x], topPoints[0]); } } //float fValue = 0.5f; ////3--2 ////| | ////0--1 //vector3 point0(-fValue, -fValue, fValue); //0 //vector3 point1(fValue, -fValue, fValue); //1 //vector3 point2(fValue, fValue, fValue); //2 //vector3 point3(-fValue, fValue, fValue); //3 //AddQuad(point0, point1, point3, point2); //Your code ends here CompileObject(a_v3Color); }
/// // Update does the work of mapping the texture onto the triangles // It now doesn't occur the cost of free/alloc data every update cycle. // It also only changes the percentage point but no other points if they have not // been modified. // // It now deals with flipped texture. If you run into this problem, just use the // sprite property and enable the methods flipX, flipY. /// void ProgressTimer::updateRadial(void) { if (!_sprite) { return; } float alpha = _percentage / 100.f; float angle = 2.f*((float)M_PI) * ( _reverseDirection ? alpha : 1.0f - alpha); // We find the vector to do a hit detection based on the percentage // We know the first vector is the one @ 12 o'clock (top,mid) so we rotate // from that by the progress angle around the _midpoint pivot Vec2 topMid(_midpoint.x, 1.f); Vec2 percentagePt = topMid.rotateByAngle(_midpoint, angle); int index = 0; Vec2 hit; if (alpha == 0.f) { // More efficient since we don't always need to check intersection // If the alpha is zero then the hit point is top mid and the index is 0. hit = topMid; index = 0; } else if (alpha == 1.f) { // More efficient since we don't always need to check intersection // If the alpha is one then the hit point is top mid and the index is 4. hit = topMid; index = 4; } else { // We run a for loop checking the edges of the texture to find the // intersection point // We loop through five points since the top is split in half float min_t = FLT_MAX; for (int i = 0; i <= kProgressTextureCoordsCount; ++i) { int pIndex = (i + (kProgressTextureCoordsCount - 1))%kProgressTextureCoordsCount; Vec2 edgePtA = boundaryTexCoord(i % kProgressTextureCoordsCount); Vec2 edgePtB = boundaryTexCoord(pIndex); // Remember that the top edge is split in half for the 12 o'clock position // Let's deal with that here by finding the correct endpoints if(i == 0){ edgePtB = edgePtA.lerp(edgePtB, 1-_midpoint.x); } else if(i == 4){ edgePtA = edgePtA.lerp(edgePtB, 1-_midpoint.x); } // s and t are returned by ccpLineIntersect float s = 0, t = 0; if(Vec2::isLineIntersect(edgePtA, edgePtB, _midpoint, percentagePt, &s, &t)) { // Since our hit test is on rays we have to deal with the top edge // being in split in half so we have to test as a segment if ((i == 0 || i == 4)) { // s represents the point between edgePtA--edgePtB if (!(0.f <= s && s <= 1.f)) { continue; } } // As long as our t isn't negative we are at least finding a // correct hitpoint from _midpoint to percentagePt. if (t >= 0.f) { // Because the percentage line and all the texture edges are // rays we should only account for the shortest intersection if (t < min_t) { min_t = t; index = i; } } } } // Now that we have the minimum magnitude we can use that to find our intersection hit = _midpoint+ ((percentagePt - _midpoint) * min_t); } // The size of the vertex data is the index from the hitpoint // the 3 is for the _midpoint, 12 o'clock point and hitpoint position. bool sameIndexCount = true; if(_vertexDataCount != index + 3){ sameIndexCount = false; CC_SAFE_FREE(_vertexData); _vertexDataCount = 0; } if(!_vertexData) { _vertexDataCount = index + 3; _vertexData = (V2F_C4B_T2F*)malloc(_vertexDataCount * sizeof(V2F_C4B_T2F)); CCASSERT( _vertexData, "CCProgressTimer. Not enough memory"); } updateColor(); if (!sameIndexCount) { // First we populate the array with the _midpoint, then all // vertices/texcoords/colors of the 12 'o clock start and edges and the hitpoint _vertexData[0].texCoords = textureCoordFromAlphaPoint(_midpoint); _vertexData[0].vertices = vertexFromAlphaPoint(_midpoint); _vertexData[1].texCoords = textureCoordFromAlphaPoint(topMid); _vertexData[1].vertices = vertexFromAlphaPoint(topMid); for(int i = 0; i < index; ++i){ Vec2 alphaPoint = boundaryTexCoord(i); _vertexData[i+2].texCoords = textureCoordFromAlphaPoint(alphaPoint); _vertexData[i+2].vertices = vertexFromAlphaPoint(alphaPoint); } } // hitpoint will go last _vertexData[_vertexDataCount - 1].texCoords = textureCoordFromAlphaPoint(hit); _vertexData[_vertexDataCount - 1].vertices = vertexFromAlphaPoint(hit); }
/** * @internal A convenience method to setup shapes of all symbols. */ void Symbol::setupSymbolTable() { SymbolProperty &openArrow = symbolTable[OpenArrow]; if (openArrow.shape.isEmpty()) { QRectF rect = openArrow.boundRect; // Defines a 'V' shape arrow fitting in the bound rect. openArrow.shape.moveTo(rect.topLeft()); openArrow.shape.lineTo(rect.center().x(), rect.bottom()); openArrow.shape.lineTo(rect.topRight()); } SymbolProperty &closedArrow = symbolTable[ClosedArrow]; if (closedArrow.shape.isEmpty()) { QRectF rect = closedArrow.boundRect; // Defines a 'V' shape arrow fitting in the bound rect. closedArrow.shape.moveTo(rect.topLeft()); closedArrow.shape.lineTo(rect.center().x(), rect.bottom()); closedArrow.shape.lineTo(rect.topRight()); closedArrow.shape.lineTo(rect.topLeft()); } SymbolProperty &crowFeet = symbolTable[CrowFeet]; if (crowFeet.shape.isEmpty()) { QRectF rect = crowFeet.boundRect; // Defines a crowFeet fitting in the bound rect. QPointF topMid(rect.center().x(), rect.top()); // left leg crowFeet.shape.moveTo(rect.bottomLeft()); crowFeet.shape.lineTo(topMid); // middle leg crowFeet.shape.moveTo(rect.center().x(), rect.bottom()); crowFeet.shape.lineTo(topMid); // right leg crowFeet.shape.moveTo(rect.bottomRight()); crowFeet.shape.lineTo(topMid); } SymbolProperty &diamond = symbolTable[Diamond]; if (diamond.shape.isEmpty()) { QRectF rect = diamond.boundRect; // Defines a 'diamond' shape fitting in the bound rect. diamond.shape.moveTo(rect.center().x(), rect.top()); diamond.shape.lineTo(rect.left(), rect.center().y()); diamond.shape.lineTo(rect.center().x(), rect.bottom()); diamond.shape.lineTo(rect.right(), rect.center().y()); diamond.shape.lineTo(rect.center().x(), rect.top()); } SymbolProperty &subset = symbolTable[Subset]; if (subset.shape.isEmpty()) { QRectF rect = subset.boundRect; // Defines an arc fitting in bound rect. qreal start = 90, span = 180; subset.shape.arcMoveTo(rect, start); subset.shape.arcTo(rect, start, span); } SymbolProperty &circle = symbolTable[Circle]; if (circle.shape.isEmpty()) { QRectF rect = circle.boundRect; // Defines a circle with a horizontal-vertical cross lines. circle.shape.addEllipse(rect); circle.shape.moveTo(rect.center().x(), rect.top()); circle.shape.lineTo(rect.center().x(), rect.bottom()); circle.shape.moveTo(rect.left(), rect.center().y()); circle.shape.lineTo(rect.right(), rect.center().y()); } }