void split(QuadraticBezier& left, QuadraticBezier& right) const { left.control = midPoint(start, control); right.control = midPoint(control, end); FloatPoint leftControlToRightControl = midPoint(left.control, right.control); left.end = leftControlToRightControl; right.start = leftControlToRightControl; left.start = start; right.end = end; }
void refine(int depth, triangle t, float** p) { if (depth == n) { t.dump(p); } else { vector3 m1 = midPoint(t.p2, t.p3).normalize(); vector3 m2 = midPoint(t.p3, t.p1).normalize(); vector3 m3 = midPoint(t.p1, t.p2).normalize(); refine(depth + 1, triangle(t.p1, m3, m2), p); refine(depth + 1, triangle(m3, t.p2, m1), p); refine(depth + 1, triangle(m1, m2, m3), p); refine(depth + 1, triangle(m2, m1, t.p3), p); } }
/** * Arrow class contructor, that creates and arrow from a start item * to the endItem * @param startItem * @param endItem * @param parentGroup */ Arrow::Arrow(DocBlock *startItem, Block *endItem, BlockGroup *parentGroup) : QGraphicsLineItem(parentGroup) { Q_ASSERT(startItem != 0);Q_ASSERT(endItem != 0);Q_ASSERT(parentGroup != 0); myStartItem = startItem; myEndItem = endItem; myColor = Qt::black; setPen(QPen(myColor, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); connect(myStartItem, SIGNAL(destroyed()), this, SLOT(deleteLater())); connect(myEndItem, SIGNAL(destroyed()), this, SLOT(deleteLater())); connect(myEndItem, SIGNAL(visibilityChanged(bool)), this, SLOT(updateVisibility(bool))); line1 = QLineF(startPoint(), midPoint()); line2 = QLineF(midPoint(), endPoint()); }
bool Beats::detected() { bool beatDetected = false; if ( currentValue() > midPoint() && lastValue() < midPoint() && currentDerivative() > derivativeMidPoint() && currentDerivative() > derivativeLimit && beatCanTrigger()) { beatDetected = true; iterationCounter = 1; } return beatDetected; }
void Hypergraph::kdPartition (int depth, int targetDepth, vector<fvec>::iterator &firstPt, vector<fvec>::iterator &lastPt, vector<float> &divisions, int divisionIdx) { if (depth>targetDepth) { return; } int nPoints = lastPt-firstPt; int nMidPoint = nPoints/2; int coord = depth%2; switch (coord) { case 0: nth_element(firstPt, firstPt+nMidPoint, lastPt, compareX); break; case 1: nth_element(firstPt, firstPt+nMidPoint, lastPt, compareY); break; } fvec &midPoint = *(firstPt+nMidPoint); divisions[divisionIdx] = midPoint(coord%2); kdPartition(depth+1, targetDepth, firstPt, firstPt+nMidPoint, divisions, 2*divisionIdx+1); kdPartition(depth+1, targetDepth, firstPt+nMidPoint, lastPt, divisions, 2*divisionIdx+2); }
/** * Subdivide triangle into 4 smaller triangles */ vector<Vec9f> Triangle::forceSubdivide(Vec9f triangle){ //final list vector<Vec9f> triangle_list; vector<cv::Point3d> vertices = convVec9fToPoint3d(triangle); //Get the mid points of each of the segments cv::Point3d p01, p12, p02; p01 = midPoint(vertices[0], vertices[1]); p12 = midPoint(vertices[1], vertices[2]); p02 = midPoint(vertices[0], vertices[2]); // Lower left sub-triangle vector<cv::Point3d> tri0; Vec9f tri0f; tri0.push_back(vertices[0]); tri0.push_back(p01); tri0.push_back(p02); tri0f = convPoint3dToVec9f(tri0); triangle_list.push_back(tri0f); // top sub-triangle vector<cv::Point3d> tri1;Vec9f tri1f; tri1.push_back(p01); tri1.push_back(vertices[1]); tri1.push_back(p12); tri1f = convPoint3dToVec9f(tri1); triangle_list.push_back(tri1f); // Lower right sub-triangle vector<cv::Point3d> tri2;Vec9f tri2f; tri2.push_back(p02); tri2.push_back(p12); tri2.push_back(vertices[2]); tri2f = convPoint3dToVec9f(tri2); triangle_list.push_back(tri2f); // center sub-triangle vector<cv::Point3d> tri3;Vec9f tri3f; tri3.push_back(p01); tri3.push_back(p12); tri3.push_back(p02); tri3f = convPoint3dToVec9f(tri3); triangle_list.push_back(tri3f); return triangle_list; }
void ofApp::sierpinsky(ofVec2f a, ofVec2f b, ofVec2f c, int level) { if (level == 0) { points.push_back(a); points.push_back(b); points.push_back(c); return; } else { ofVec2f ab = midPoint(a, b); ofVec2f bc = midPoint(b, c); ofVec2f ca = midPoint(c, a); sierpinsky(a, ab, ca, level - 1); sierpinsky(ab, b, bc, level - 1); sierpinsky(ca, bc, c, level - 1); } drawFigure(points, TRIANGLE); }
/* * Subdivide one triangle to four triangles when it has angles to the center are larger than 45.0 dereees. */ vector< vector<cv::Point3d> > Triangle::subdivide(vector<cv::Point3d> vertices){ double max_angle = getMaxAngle(vertices); vector < vector<cv::Point3d> > triangle_list; cv::Point3d p01, p12, p02; if(max_angle > m_MAX_ANGLE){ if(vertices.size() == 3){ p01 = midPoint(vertices[0], vertices[1]); p12 = midPoint(vertices[1], vertices[2]); p02 = midPoint(vertices[0], vertices[2]); } // Lower left sub-triangle vector<cv::Point3d> tri0; tri0.push_back(vertices[0]); tri0.push_back(p01); tri0.push_back(p02); triangle_list.push_back(tri0); // top sub-triangle vector<cv::Point3d> tri1; tri1.push_back(p01); tri1.push_back(vertices[1]); tri1.push_back(p12); triangle_list.push_back(tri1); // Lower right sub-triangle vector<cv::Point3d> tri2; tri2.push_back(p02); tri2.push_back(p12); tri2.push_back(vertices[2]); triangle_list.push_back(tri2); // center sub-triangle vector<cv::Point3d> tri3; tri3.push_back(p01); tri3.push_back(p12); tri3.push_back(p02); triangle_list.push_back(tri3); }else{ triangle_list.push_back(vertices); } return triangle_list; }
void structures2() { Point pt; pt.x = 100.0; pt.y = 75.0; Point mid = midPoint(pt); printf("Mid is %f, %f\n", mid.x, mid.y); }
/* * getMidPoint * * parameter p0 - int * parameter p1 - int * return - float * */ float * BoundingBox::getMidPoint(int p0, int p1) { float * point0; float * point1; float * point; point0 = getCorner(p0); point1 = getCorner(p1); point = midPoint(point0, point1); delete[] point0; delete[] point1; return point; } // end getMidPoint()
/** * Paints the specified arrow * @return the end point */ void Arrow::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) { // if (myStartItem->collidesWithItem(myEndItem)) return; QPen myPen = pen(); myPen.setColor(myColor); qreal arrowSize = 10; painter->setPen(myPen); painter->setBrush(myColor); setLine(QLineF(startPoint(), endPoint())); line1 = QLineF(startPoint(), midPoint()); line2 = QLineF(midPoint(), endPoint()); double angle = acos(line1.dx() / line1.length()); if (line1.dy() >= 0) angle = (Pi * 2) - angle; QPointF arrowP1 = line1.p1() + QPointF(sin(angle + Pi / 3) * arrowSize, cos(angle + Pi / 3) * arrowSize); QPointF arrowP2 = line1.p1() + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, cos(angle + Pi - Pi / 3) * arrowSize); //arrow corner cornerLine1= QLineF(endPoint(),endPoint()+QPointF(0,10)); cornerLine2= QLineF(endPoint(),endPoint()-QPointF(10,0)); arrowHead.clear(); arrowHead << line1.p1() << arrowP1 << arrowP2; painter->setRenderHint(QPainter::Antialiasing); painter->drawLine(line1); painter->drawLine(line2); painter->drawLine(cornerLine1); painter->drawLine(cornerLine2); painter->drawPolygon(arrowHead); }
//--------------------------------------------------------- // Spliting them into 4 smaller triangles //---------------------------------------------------------- void subDivideTriangles(int level, std::vector<TriangleIndices> *facesIn, std::vector<TriangleIndices> *facesOut, std::vector<STVector3> *vertices) { std::multimap<long, int> midPointIndices; int nFaces = facesIn->size(); for (int i = 0; i < level; i++) { for(int j = 0; j < (int)facesIn->size(); ++j) { int a = midPoint((*facesIn)[j].i1, (*facesIn)[j].i2, &midPointIndices, vertices); int b = midPoint((*facesIn)[j].i2, (*facesIn)[j].i3, &midPointIndices, vertices); int c = midPoint((*facesIn)[j].i3, (*facesIn)[j].i1, &midPointIndices, vertices); facesOut->push_back(makeTIndices((*facesIn)[j].i1, a, c)); facesOut->push_back(makeTIndices((*facesIn)[j].i2, b, a)); facesOut->push_back(makeTIndices((*facesIn)[j].i3, c, b)); facesOut->push_back(makeTIndices(a, b, c)); } (*facesIn) = (*facesOut); nFaces=facesIn->size(); } }
void BezierCurveEvaluator::divide(Point P[], Point L[], Point R[]) const { L[0] = P[0]; L[1] = midPoint(P[0], P[1]); Point H = midPoint(P[1], P[2]); L[2] = midPoint(L[1], H); R[3] = P[3]; R[2] = midPoint(P[2], P[3]); R[1] = midPoint(P[2], H); R[0] = midPoint(L[2], R[1]); L[3] = R[0]; }
int binarySearchJval(Jval *a, Jval item, int low, int high, int (*compare)(Jval*, Jval*)) { int mid = midPoint(low, high); int res; if(low > high) { return -1; } res = compare(&a[mid], &item); if(res > 0) { return binarySearchJval(a, item, low, mid - 1, compare); } if(res < 0) { return binarySearchJval(a, item, mid + 1, high, compare); } return mid; }
bool QgsGeometryUtils::segmentMidPoint( const QgsPointV2& p1, const QgsPointV2& p2, QgsPointV2& result, double radius, const QgsPointV2& mousePos ) { QgsPointV2 midPoint(( p1.x() + p2.x() ) / 2.0, ( p1.y() + p2.y() ) / 2.0 ); double midDist = sqrt( sqrDistance2D( p1, midPoint ) ); if ( radius < midDist ) { return false; } double centerMidDist = sqrt( radius * radius - midDist * midDist ); double dist = radius - centerMidDist; double midDx = midPoint.x() - p1.x(); double midDy = midPoint.y() - p1.y(); //get the four possible midpoints QList<QgsPointV2> possibleMidPoints; possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() - midDy, midPoint.y() + midDx ), dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() - midDy, midPoint.y() + midDx ), 2 * radius - dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() + midDy, midPoint.y() - midDx ), dist ) ); possibleMidPoints.append( pointOnLineWithDistance( midPoint, QgsPointV2( midPoint.x() + midDy, midPoint.y() - midDx ), 2 * radius - dist ) ); //take the closest one double minDist = std::numeric_limits<double>::max(); int minDistIndex = -1; for ( int i = 0; i < possibleMidPoints.size(); ++i ) { double currentDist = sqrDistance2D( mousePos, possibleMidPoints.at( i ) ); if ( currentDist < minDist ) { minDistIndex = i; minDist = currentDist; } } if ( minDistIndex == -1 ) { return false; } result = possibleMidPoints.at( minDistIndex ); return true; }
void split(CubicBezier& left, CubicBezier& right) const { FloatPoint startToControl1 = midPoint(control1, control2); left.start = start; left.control1 = midPoint(start, control1); left.control2 = midPoint(left.control1, startToControl1); right.control2 = midPoint(control2, end); right.control1 = midPoint(right.control2, startToControl1); right.end = end; FloatPoint leftControl2ToRightControl1 = midPoint(left.control2, right.control1); left.end = leftControl2ToRightControl1; right.start = leftControl2ToRightControl1; }
void problem18() { GLubyte black[] = {0,0,0}; glm::vec3 v1(100,200,1), v2(200,300,1), v3(300,200,1); glm::mat3 mat(0.5, 0, 0, 0, 0.5, 0, 0, 0, 1); glm::vec3 midPoint(((v1.x + v2.x + v3.x) / 3.0), ((v1.y + v2.y + v3.y) / 3.0), 1); v1 -= midPoint; v2 -= midPoint; v3 -= midPoint; v1 = mat * v1; v2 = mat * v2; v3 = mat * v3; v1 += midPoint; v2 += midPoint; v3 += midPoint; drawTriangle(v1,v2,v3, black); }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk::mesh::Entity *>::iterator& element_pool, stk::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk::mesh::EntityId, stk::mesh::EntityId> line_tuple_type; static vector<line_tuple_type> elems(2); CellTopology cell_topo(cell_topo_data); const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); std::vector<stk::mesh::Part*> add_parts; std::vector<stk::mesh::Part*> remove_parts; add_parts = m_toParts; unsigned num_nodes_on_edge = new_sub_entity_nodes[m_eMesh.edge_rank()][0].size(); if (!num_nodes_on_edge) return; double coord_x[3]; for (int iedge = 0; iedge < 1; iedge++) { //double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); //double * mp = midPoint(FACE_COORD(iedge,0), FACE_COORD(iedge,1), eMesh.get_spatial_dim(), coord_x); double * mp = midPoint(VERT_COORD(0), VERT_COORD(1), eMesh.get_spatial_dim(), coord_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } // FIXME nodeRegistry.makeCentroidCoords(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.addToExistingParts(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); nodeRegistry.interpolateFields(*const_cast<stk::mesh::Entity *>(&element), m_primaryEntityRank, 0u); Elem::CellTopology elem_celltopo = Elem::getCellTopology< FromTopology >(); const Elem::RefinementTopology* ref_topo_p = Elem::getRefinementTopology(elem_celltopo); const Elem::RefinementTopology& ref_topo = *ref_topo_p; #ifndef NDEBUG unsigned num_child = ref_topo.num_child(); VERIFY_OP(num_child, == , 2, "createNewElements num_child problem"); bool homogeneous_child = ref_topo.homogeneous_child(); VERIFY_OP(homogeneous_child, ==, true, "createNewElements homogeneous_child"); #endif // new_sub_entity_nodes[i][j] //const UInt * const * child_nodes() const { //const UInt * child_node_0 = ref_topo.child_node(0); typedef Elem::StdMeshObjTopologies::RefTopoX RefTopoX; RefTopoX& l2 = Elem::StdMeshObjTopologies::RefinementTopologyExtra< FromTopology > ::refinement_topology; #define CENTROID_N NN(m_primaryEntityRank,0) for (unsigned iChild = 0; iChild < 2; iChild++) { unsigned EN[2]; for (unsigned jNode = 0; jNode < 2; jNode++) { unsigned childNodeIdx = ref_topo.child_node(iChild)[jNode]; #ifndef NDEBUG unsigned childNodeIdxCheck = l2[childNodeIdx].ordinal_of_node; VERIFY_OP(childNodeIdx, ==, childNodeIdxCheck, "childNodeIdxCheck"); #endif unsigned inode=0; if (l2[childNodeIdx].rank_of_subcell == 0) inode = VERT_N(l2[childNodeIdx].ordinal_of_subcell); else if (l2[childNodeIdx].rank_of_subcell == 1) inode = EDGE_N(l2[childNodeIdx].ordinal_of_subcell); // else if (l2[childNodeIdx].rank_of_subcell == 2) // inode = CENTROID_N; EN[jNode] = inode; } elems[iChild] = line_tuple_type(EN[0], EN[1]); } #undef CENTROID_N for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk::mesh::Entity& newElement = *(*element_pool); #if 0 if (proc_rank_field && proc_rank_field->rank() == m_eMesh.edge_rank()) //&& m_eMesh.get_spatial_dim()==1) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } #endif stk::mesh::FieldBase * proc_rank_field_edge = m_eMesh.get_field("proc_rank_edge"); if (proc_rank_field_edge) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field_edge) , newElement ); fdata[0] = double(newElement.owner_rank()); //fdata[0] = 1234.56; if (0) std::cout << "P[" << m_eMesh.get_rank() << "] tmp set proc_rank_field_edge to value = " << newElement.owner_rank() << " for side element = " << newElement.identifier() << std::endl; } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void MyPrimitive::GenerateCone(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 topPoint(0.00f, a_fHeight / 2, 0.00f); //top vertex vector3 midPoint(0.00f, -(a_fHeight / 2), 0.00f); //mid-base vertex 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)); } //create cone for (int x = 0; x < basePoints.size(); x++) { AddVertexPosition(topPoint); AddVertexPosition(basePoints[x]); if (x == basePoints.size() - 1) { AddVertexPosition(basePoints[0]); } else { AddVertexPosition(basePoints[x + 1]); } } //create base for (int x = 0; x < basePoints.size(); x++) { AddVertexPosition(midPoint); if (x == basePoints.size() - 1) { AddVertexPosition(basePoints[0]); } else { AddVertexPosition(basePoints[x + 1]); } AddVertexPosition(basePoints[x]); } //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); }
void FindCircle::imageCallback(const sensor_msgs::ImageConstPtr& msg) { if (image->bpp != msg->step / msg->width || image->width != msg->width || image->height != msg->height) { delete image; ROS_DEBUG("Readjusting image format from %ix%i %ibpp, to %ix%i %ibpp.", image->width, image->height, image->bpp, msg->width, msg->height, msg->step / msg->width); image = new CRawImage(msg->width, msg->height, msg->step / msg->width); } memcpy(image->data, (void*) &msg->data[0], msg->step * msg->height); circle_detection::detection_results_array tracked_objects; tracked_objects.header = msg->header; visualization_msgs::MarkerArray marker_list; std::vector<STrackedObject> circles; //search image for circles for (int i = 0; i < MAX_PATTERNS; i++) { SSegment lastSegment = currentSegmentArray[i]; // currentSegmentArray[i] = detectorArray[i]->findSegment(image, lastSegment); currentSegmentArray[i] = detectorArray[i]->findSegment(image, lastSegment); if (currentSegmentArray[i].valid) { STrackedObject sTrackedObject = trans->transform(currentSegmentArray[i]); // Filter error values if (isnan(sTrackedObject.x)) continue; if (isnan(sTrackedObject.y)) continue; if (isnan(sTrackedObject.z)) continue; if (isnan(sTrackedObject.roll)) continue; if (isnan(sTrackedObject.pitch)) continue; if (isnan(sTrackedObject.yaw)) continue; circles.push_back(sTrackedObject); } } // std::cout << "found " << circles.size() << " circles\n"; // Early rejection if the candidate circles are just not enough if (circles.size()<NUM_CIRCLES) { return; } // Search for the nearest circle to predefined center point (3D) const int nearestIx = nearest3DObjIx(circles,SEARCH_X,SEARCH_Y,SEARCH_Z); // Search for the knn (k=5) of the nearest point std::vector<std::pair<int,double> > knn = knn3DObjIx(circles,circles[nearestIx].x,circles[nearestIx].y,circles[nearestIx].z); // Early rejection if the candidate circles are just not enough // if (knn.size()<NUM_CIRCLES) { // std::cout << "Not enough circles! " << knn.size() << std::endl; // return; // } std::vector<STrackedObject> knnCircles; for (int i = 0; i < NUM_CIRCLES; i++) { knnCircles.push_back(circles[knn[i].first]); } std::pair<int,int> firstAndThirdCircles = largestDistIndices(knnCircles); // The first and third circles std::pair<float,float> midXYFirstAndThird = midPoint(knnCircles, firstAndThirdCircles); // The middle point between first and third circles std::pair<float,float> midXYRef = midPoint(knnCircles); // The middle point of the 5 points double refAngle = angleBetweenPts(midXYFirstAndThird,midXYRef) - 0.5*M_PI ; // The reference line if (refAngle<0) refAngle += ONE_ROUND_RADIAN; // Turn it to [0, 2PI) // std::cout << refAngle/M_PI*180 << std::endl; for (std::vector<STrackedObject>::iterator it=knnCircles.begin(); it!=knnCircles.end(); ++it) { double angleToRef = angleBetweenPts( std::pair<float,float>(it->segment.x,it->segment.y),midXYRef) - refAngle; it->segment.angleToRef = (angleToRef>=0)? angleToRef : angleToRef+ONE_ROUND_RADIAN; } // Sort the detected circles according to the angle to reference line std::sort(knnCircles.begin(),knnCircles.end(),circlePositionCompare); // Turn it back to [-PI, PI) const double angle_offset = refAngle>ONE_ROUND_RADIAN/2 ? refAngle-ONE_ROUND_RADIAN : refAngle ; // /* // Sanity check: compare the second line's orientation // Get the angle from 3rd circle to 4th circle double angle_0to2 = angleBetweenPts( std::pair<float,float>((knnCircles.begin())->segment.x,(knnCircles.begin())->segment.y), std::pair<float,float>((knnCircles.begin()+2)->segment.x,(knnCircles.begin()+2)->segment.y) ); double angle_4to3 = angleBetweenPts( std::pair<float,float>((knnCircles.begin()+4)->segment.x,(knnCircles.begin()+4)->segment.y), std::pair<float,float>((knnCircles.begin()+3)->segment.x,(knnCircles.begin()+3)->segment.y) ); if (abs(angle_0to2-angle_4to3)>ANGLE_THRLD_RATE) { std::cout << "lines doesn't allign!" << std::endl; return; } // */ int i =0; int personId = 0; for (std::vector<STrackedObject>::iterator it=knnCircles.begin(); it!=knnCircles.end(); ++it) { double angle = ((it->segment.angle-angle_offset)/M_PI+1)/2*numCommands; int digit = (int)(floor(angle+0.5)+2) % numCommands; personId += digit * pow(4,i); // std::cout << i << ": " << it->segment.angleToRef/M_PI*180 << " " << it->segment.bwRatio << " " << digit << std::endl; // temp value to hold current detection circle_detection::detection_results objectsToAdd; // Convert to ROS standard Coordinate System objectsToAdd.pose.position.x = -(*it).y; objectsToAdd.pose.position.y = -(*it).z; objectsToAdd.pose.position.z = (*it).x; // Convert YPR to Quaternion tf::Quaternion q; q.setRPY((*it).roll, (*it).pitch, (*it).yaw); objectsToAdd.pose.orientation.x = q.getX(); objectsToAdd.pose.orientation.y = q.getY(); objectsToAdd.pose.orientation.z = q.getZ(); objectsToAdd.pose.orientation.w = q.getW(); // This needs to be replaced with a unique label as ratio is unreliable objectsToAdd.bwratio = (*it).bwratio; objectsToAdd.circleId = i++; objectsToAdd.digit = digit; // Hardcoded values need to be replaced objectsToAdd.objectsize.x = 3; objectsToAdd.objectsize.y = 3; objectsToAdd.objectsize.z = 0; tracked_objects.tracked_objects.push_back(objectsToAdd); } tracked_objects.personId = personId; if(tracked_objects.tracked_objects.size()!=NUM_CIRCLES) { return; } if (tracked_objects.tracked_objects.size() > 0) { std::cout << "publish: " << personId <<std::endl; std::cout << "--" << std::endl; pub.publish(tracked_objects); } memcpy((void*) &msg->data[0], image->data, msg->step * msg->height); imdebug.publish(msg); }
int main(int argc, char *argv[]) { if (argc != 10 || !strncmp(argv[1],"-h",2)) { puts("DrawLineSegment: Prints a line through two given points"); puts("USAGE: ./DrawLineSegment x"); return 0; } initscr(); /* Start curses mode */ raw(); /* Line buffering disabled */ noecho(); /* Don't echo() while we do getch */ start_color(); /* Start color */ init_pair(1, COLOR_RED, COLOR_RED); init_pair(2, COLOR_BLUE, COLOR_BLUE); attron(COLOR_PAIR(1)); curs_set(0); double x1 = atof(argv[1]); double y1 = atof(argv[2]); double x2 = atof(argv[3]); double y2 = atof(argv[4]); double x3 = atof(argv[5]); double y3 = atof(argv[6]); double x4 = atof(argv[7]); double y4 = atof(argv[8]); Pair mid1 = midPoint(x1,y1,x2,y2); Pair mid2 = midPoint(x3,y3,x4,y4); Pair mid = midPoint(mid1.x,mid1.y,mid2.x,mid2.y); Pair rpoint1; Pair rpoint2; Pair rpoint3; Pair rpoint4; for (int i = 0; i < 1080; i++) { rpoint1 = rotateDPoint(mid.x,mid.y,x1,y1,i); rpoint2 = rotateDPoint(mid.x,mid.y,x2,y2,i); rpoint3 = rotateDPoint(mid.x,mid.y,x3,y3,i); rpoint4 = rotateDPoint(mid.x,mid.y,x4,y4,i); //draw the starting line //draw the midpoint attron(COLOR_PAIR(2)); drawPair(mid); //draw rotated about the middle point attron(COLOR_PAIR(1)); drawQuadrilateral(rpoint1.x,rpoint1.y, rpoint2.x,rpoint2.y, rpoint3.x,rpoint3.y, rpoint4.x,rpoint4.y); //draw the shape refresh(); /* Print it on to the real screen */ //sleep() wasn't working too well for me for (int j = 0; j <= atol(argv[5])*10000; j++); clear(); } getch(); /* Wait for user input */ endwin(); /* End curses mode */ return 0; }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk::mesh::Entity *>::iterator& element_pool, stk::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk::mesh::EntityId, stk::mesh::EntityId, stk::mesh::EntityId, stk::mesh::EntityId> quad_tuple_type; static vector<quad_tuple_type> elems(4); CellTopology cell_topo(cell_topo_data); const stk::mesh::PairIterRelation elem_nodes = element.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); //stk::mesh::Part & active = mesh->ActivePart(); //stk::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk::mesh::Part*> add_parts; std::vector<stk::mesh::Part*> remove_parts; //add_parts.push_back( &active ); //FIXME //add_parts.push_back( const_cast<mesh::Part*>( eMesh.getPart(m_toTopoPartName) )); add_parts = m_toParts; double tmp_x[3]; for (int iedge = 0; iedge < 4; iedge++) { double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), tmp_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 << " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } nodeRegistry.makeCentroidCoords(*const_cast<stk::mesh::Entity *>(&element), m_eMesh.element_rank(), 0u); // new_sub_entity_nodes[i][j] #define CENTROID_N NN(m_primaryEntityRank,0) elems[0] = quad_tuple_type(VERT_N(0), EDGE_N(0), CENTROID_N, EDGE_N(3)); elems[1] = quad_tuple_type(VERT_N(1), EDGE_N(1), CENTROID_N, EDGE_N(0)); elems[2] = quad_tuple_type(VERT_N(2), EDGE_N(2), CENTROID_N, EDGE_N(1)); elems[3] = quad_tuple_type(VERT_N(3), EDGE_N(3), CENTROID_N, EDGE_N(2)); #undef CENTROID_N // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { stk::mesh::Entity& newElement = *(*element_pool); if (proc_rank_field) { double *fdata = stk::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<3>()), 3); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void simpleFluidEmitter::omniFluidEmitter( MFnFluid& fluid, const MMatrix& fluidWorldMatrix, int plugIndex, MDataBlock& block, double dt, double conversion, double dropoff ) //============================================================================== // // Method: // // simpleFluidEmitter::omniFluidEmitter // // Description: // // Emits fluid from a point, or from a set of object control points. // // Parameters: // // fluid: fluid into which we are emitting // fluidWorldMatrix: object->world matrix for the fluid // plugIndex: identifies which fluid connected to the emitter // we are emitting into // block: datablock for the emitter, to retrieve attribute // values // dt: time delta for this frame // conversion: mapping from UI emission rates to internal units // dropoff: specifies how much emission rate drops off as // we move away from each emission point. // // Notes: // // If no owner object is present for the emitter, we simply emit from // the emitter position. If an owner object is present, then we emit // from each control point of that object in an identical fashion. // // To associate an owner object with an emitter, use the // addDynamic MEL command, e.g. "addDynamic simpleFluidEmitter1 pPlane1". // //============================================================================== { // find the positions that we need to emit from // MVectorArray emitterPositions; // first, try to get them from an owner object, which will have its // "ownerPositionData" attribute feeding into the emitter. These // values are in worldspace // bool gotOwnerPositions = false; MObject ownerShape = getOwnerShape(); if( ownerShape != MObject::kNullObj ) { MStatus status; MDataHandle hOwnerPos = block.inputValue( mOwnerPosData, &status ); if( status == MS::kSuccess ) { MObject dOwnerPos = hOwnerPos.data(); MFnVectorArrayData fnOwnerPos( dOwnerPos ); MVectorArray posArray = fnOwnerPos.array( &status ); if( status == MS::kSuccess ) { // assign vectors from block to ownerPosArray. // for( unsigned int i = 0; i < posArray.length(); i ++ ) { emitterPositions.append( posArray[i] ); } gotOwnerPositions = true; } } } // there was no owner object, so we just use the emitter position for // emission. // if( !gotOwnerPositions ) { MPoint emitterPos = getWorldPosition(); emitterPositions.append( emitterPos ); } // get emission rates for density, fuel, heat, and emission color // double densityEmit = fluidDensityEmission( block ); double fuelEmit = fluidFuelEmission( block ); double heatEmit = fluidHeatEmission( block ); bool doEmitColor = fluidEmitColor( block ); MColor emitColor = fluidColor( block ); // rate modulation based on frame time, user value conversion factor, and // standard emitter "rate" value (not actually exposed in most fluid // emitters, but there anyway). // double theRate = getRate(block) * dt * conversion; // get voxel dimensions and sizes (object space) // double size[3]; unsigned int res[3]; fluid.getDimensions( size[0], size[1], size[2] ); fluid.getResolution( res[0], res[1], res[2] ); // voxel sizes double dx = size[0] / res[0]; double dy = size[1] / res[1]; double dz = size[2] / res[2]; // voxel centers double Ox = -size[0]/2; double Oy = -size[1]/2; double Oz = -size[2]/2; // emission will only happen for voxels whose centers lie within // "minDist" and "maxDist" of an emitter position // double minDist = getMinDistance( block ); double maxDist = getMaxDistance( block ); // bump up the min/max distance values so that they // are both > 0, and there is at least about a half // voxel between the min and max values, to prevent aliasing // artifacts caused by emitters missing most voxel centers // MTransformationMatrix fluidXform( fluidWorldMatrix ); double fluidScale[3]; fluidXform.getScale( fluidScale, MSpace::kWorld ); // compute smallest voxel diagonal length double wsX = fabs(fluidScale[0]*dx); double wsY = fabs(fluidScale[1]*dy); double wsZ = fabs(fluidScale[2]*dz); double wsMin = MIN( MIN( wsX, wsY), wsZ ); double wsMax = MAX( MAX( wsX, wsY), wsZ ); double wsDiag = wsMin * sqrt(3.0); // make sure emission range is bigger than 0.5 voxels if ( maxDist <= minDist || maxDist <= (wsDiag/2.0) ) { if ( minDist < 0 ) minDist = 0; maxDist = minDist + wsDiag/2.0; dropoff = 0; } // Now, it's time to actually emit into the fluid: // // foreach emitter point // foreach voxel // - select some points in the voxel // - compute a dropoff function from the emitter point // - emit an appropriate amount of fluid into the voxel // // Since we've already expanded the min/max distances to cover // the smallest voxel dimension, we should only need 1 sample per // voxel, unless the voxels are highly non-square. We increase the // number of samples in these cases. // // If the "jitter" flag is enabled, we jitter each sample position, // using the rangen() function, which keeps track of independent // random states for each fluid, to make sure that results are // repeatable for multiple simulation runs. // // basic sample count int numSamples = 1; // increase samples if necessary for non-square voxels if(wsMin >.00001) { numSamples = (int)(wsMax/wsMin + .5); if(numSamples > 8) numSamples = 8; if(numSamples < 1) numSamples = 1; } bool jitter = fluidJitter(block); if( !jitter ) { // I don't have a good uniform sample generator for an // arbitrary number of samples. It would be a good idea to use // one here. For now, just use 1 sample for the non-jittered case. // numSamples = 1; } for( unsigned int p = 0; p < emitterPositions.length(); p++ ) { MPoint emitterWorldPos = emitterPositions[p]; // loop through all voxels, looking for ones that lie at least // partially within the dropoff field around this emitter point // for( unsigned int i = 0; i < res[0]; i++ ) { double x = Ox + i*dx; for( unsigned int j = 0; j < res[1]; j++ ) { double y = Oy + j*dy; for( unsigned int k = 0; k < res[2]; k++ ) { double z = Oz + k*dz; int si; for( si = 0; si < numSamples; si++ ) { // compute sample point (fluid object space) // double rx, ry, rz; if( jitter ) { rx = x + randgen()*dx; ry = y + randgen()*dy; rz = z + randgen()*dz; } else { rx = x + 0.5*dx; ry = y + 0.5*dy; rz = z + 0.5*dz; } // compute distance from sample to emitter point // MPoint point( rx, ry, rz ); point *= fluidWorldMatrix; MVector diff = point - emitterWorldPos; double distSquared = diff * diff; double dist = diff.length(); // discard if outside min/max range // if( (dist < minDist) || (dist > maxDist) ) { continue; } // drop off the emission rate according to the falloff // parameter, and divide to accound for multiple samples // in the voxel // double distDrop = dropoff * distSquared; double newVal = theRate * exp( -distDrop ) / (double)numSamples; // emit density/heat/fuel/color into the current voxel // if( newVal != 0 ) { fluid.emitIntoArrays( (float) newVal, i, j, k, (float)densityEmit, (float)heatEmit, (float)fuelEmit, doEmitColor, emitColor ); } float *fArray = fluid.falloff(); if( fArray != NULL ) { MPoint midPoint( x+0.5*dx, y+0.5*dy, z+0.5*dz ); midPoint.x *= 0.2; midPoint.y *= 0.2; midPoint.z *= 0.2; float fdist = (float) sqrt( midPoint.x*midPoint.x + midPoint.y*midPoint.y + midPoint.z*midPoint.z ); fdist /= sqrtf(3.0f); fArray[fluid.index(i,j,k)] = 1.0f-fdist; } } } } } } }
KdNode* KdNode::buildTree(std::vector<Triangle*>& tris, int depth) { KdNode* node = new KdNode(); node->m_triangles = tris; node->leftChild = NULL; node->rightChild = NULL; node->m_boxBV = new Box(); //node->Print(); if (tris.size() == 0){ return node; } if (tris.size() == 1) { node->m_boxBV = tris[0]->m_boxBV; node->leftChild = new KdNode(); node->rightChild = new KdNode(); node->leftChild->m_triangles = std::vector<Triangle*>(); node->rightChild->m_triangles = std::vector<Triangle*>(); return node; } //get box surrounding all triangles //node->m_boxBV = tris[0]->m_boxBV; for (unsigned int i=0; i < tris.size(); i++){ node->m_boxBV = node->m_boxBV->Union(*(tris[i]->m_boxBV)); } glm::dvec3 midPoint(0.0); for (unsigned int i = 0; i < tris.size(); i++){ //find midpoint of all triangles midPoint = midPoint + (tris[i]->m_boxBV->Center() * (1.0 / tris.size())); } std::vector<Triangle*> left_tris; std::vector<Triangle*> right_tris; int axis = node->m_boxBV->MaxExtent(); for(unsigned int i=0; i < tris.size();i++){ //split triangles based on their midpoints avg switch(axis){ case 0://x axis if (midPoint.x >= tris[i]->m_boxBV->Center().x){ right_tris.push_back(tris[i]); } else{ left_tris.push_back(tris[i]); } case 1:// y axis if (midPoint.y >= tris[i]->m_boxBV->Center().y){ right_tris.push_back(tris[i]); } else{ left_tris.push_back(tris[i]); } case 2:// z axis if (midPoint.z >= tris[i]->m_boxBV->Center().z){ right_tris.push_back(tris[i]); } else{ left_tris.push_back(tris[i]); } } } if (left_tris.empty() && !right_tris.empty()){ left_tris = right_tris; } if (right_tris.empty() && !left_tris.empty()){ right_tris = left_tris; } int matches = 0; for (unsigned int i=0; i < left_tris.size(); i++){ for (unsigned int j=0; j < right_tris.size();j++){ if (left_tris[i] == right_tris[i]){ matches++; } } } if ((float)matches / left_tris.size() < .5 && (float)matches / right_tris.size() < .5) { node->leftChild = buildTree(left_tris, depth+1); node->rightChild = buildTree(right_tris, depth+1); //std::cout << "depth: " << depth << std::endl; } else{ node->leftChild = new KdNode(); node->rightChild = new KdNode(); node->leftChild->m_triangles = std::vector<Triangle*>(); node->rightChild->m_triangles = std::vector<Triangle*>(); } //node->Print(); return node; }
void createNewElements(percept::PerceptMesh& eMesh, NodeRegistry& nodeRegistry, stk_classic::mesh::Entity& element, NewSubEntityNodesType& new_sub_entity_nodes, vector<stk_classic::mesh::Entity *>::iterator& element_pool, stk_classic::mesh::FieldBase *proc_rank_field=0) { const CellTopologyData * const cell_topo_data = stk_classic::percept::PerceptMesh::get_cell_topology(element); typedef boost::tuple<stk_classic::mesh::EntityId, stk_classic::mesh::EntityId, stk_classic::mesh::EntityId> tri_tuple_type; static vector<tri_tuple_type> elems(6); CellTopology cell_topo(cell_topo_data); const stk_classic::mesh::PairIterRelation elem_nodes = element.relations(stk_classic::mesh::fem::FEMMetaData::NODE_RANK); //stk_classic::mesh::Part & active = mesh->ActivePart(); //stk_classic::mesh::Part & quad4 = mesh->QuadPart(); std::vector<stk_classic::mesh::Part*> add_parts; std::vector<stk_classic::mesh::Part*> remove_parts; //add_parts.push_back( &active ); //FIXME //add_parts.push_back( const_cast<mesh::Part*>( eMesh.getPart(m_toTopoPartName) )); add_parts = m_toParts; /** \node[above] at (p4.side 1){2}; \node[left] at (p4.side 2){3}; \node[below] at (p4.side 3){0}; \node[right] at (p4.side 4){1}; */ double tmp_x[3]; for (int iedge = 0; iedge < 4; iedge++) { double * mp = midPoint(EDGE_COORD(iedge,0), EDGE_COORD(iedge,1), eMesh.get_spatial_dim(), tmp_x); if (!EDGE_N(iedge)) { std::cout << "P[" << eMesh.get_rank() << " nid ## = 0 << " << std::endl; } eMesh.createOrGetNode(EDGE_N(iedge), mp); } elems[0] = tri_tuple_type(VERT_N(0), EDGE_N(0), EDGE_N(3)); elems[1] = tri_tuple_type(VERT_N(1), EDGE_N(1), EDGE_N(0)); elems[2] = tri_tuple_type(EDGE_N(0), EDGE_N(1), EDGE_N(3)); elems[3] = tri_tuple_type(VERT_N(2), EDGE_N(2), EDGE_N(1)); elems[4] = tri_tuple_type(VERT_N(3), EDGE_N(3), EDGE_N(2)); elems[5] = tri_tuple_type(EDGE_N(2), EDGE_N(3), EDGE_N(1)); // write a diagram of the refinement pattern as a vtk file, or a latex/tikz/pgf file #define WRITE_DIAGRAM 0 #if WRITE_DIAGRAM #endif for (unsigned ielem=0; ielem < elems.size(); ielem++) { //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); //stk_classic::mesh::Entity& newElement = eMesh.get_bulk_data()->declare_entity(Element, *element_id_pool, eMesh.getPart(interface_table::shards_Triangle_3) ); stk_classic::mesh::Entity& newElement = *(*element_pool); if (proc_rank_field) { double *fdata = stk_classic::mesh::field_data( *static_cast<const ScalarFieldType *>(proc_rank_field) , newElement ); //fdata[0] = double(m_eMesh.get_rank()); fdata[0] = double(newElement.owner_rank()); } //eMesh.get_bulk_data()->change_entity_parts( newElement, add_parts, remove_parts ); change_entity_parts(eMesh, element, newElement); { if (!elems[ielem].get<0>()) { std::cout << "P[" << eMesh.get_rank() << " nid = 0 << " << std::endl; exit(1); } } eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<0>()), 0); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<1>()), 1); eMesh.get_bulk_data()->declare_relation(newElement, eMesh.createOrGetNode(elems[ielem].get<2>()), 2); set_parent_child_relations(eMesh, element, newElement, ielem); element_pool++; } }
void GuiTextEditSliderCtrl::onRender(Point2I offset, const RectI &updateRect) { if(mTextAreaHit != None) { U32 elapseTime = Sim::getCurrentTime() - mMouseDownTime; if(elapseTime > 750 || mTextAreaHit == Slider) { timeInc(elapseTime); mIncCounter += mMulInc; if(mIncCounter >= 1.0f || mIncCounter <= -1.0f) { mValue = (mMulInc > 0.0f) ? mValue+mIncAmount : mValue-mIncAmount; mIncCounter = (mIncCounter > 0.0f) ? mIncCounter-1 : mIncCounter+1; checkRange(); setValue(); mCursorPos = 0; } } } Parent::onRender(offset, updateRect); Point2I start(offset.x + getWidth() - 14, offset.y); Point2I midPoint(start.x + 7, start.y + (getExtent().y/2)); GFX->getDrawUtil()->drawRectFill(Point2I(start.x+1,start.y+1), Point2I(start.x+13,start.y+getExtent().y-1) , mProfile->mFillColor); GFX->getDrawUtil()->drawLine(start, Point2I(start.x, start.y+getExtent().y),mProfile->mFontColor); GFX->getDrawUtil()->drawLine(Point2I(start.x,midPoint.y), Point2I(start.x+14,midPoint.y), mProfile->mFontColor); GFXVertexBufferHandle<GFXVertexPCT> verts(GFX, 6, GFXBufferTypeVolatile); verts.lock(); verts[0].color.set( 0, 0, 0 ); verts[1].color.set( 0, 0, 0 ); verts[2].color.set( 0, 0, 0 ); verts[3].color.set( 0, 0, 0 ); verts[4].color.set( 0, 0, 0 ); verts[5].color.set( 0, 0, 0 ); if(mTextAreaHit == ArrowUp) { verts[0].point.set( (F32)midPoint.x, (F32)start.y + 1.0f, 0.0f ); verts[1].point.set( (F32)start.x + 11.0f, (F32)midPoint.y - 2.0f, 0.0f ); verts[2].point.set( (F32)start.x + 3.0f, (F32)midPoint.y - 2.0f, 0.0f ); } else { verts[0].point.set( (F32)midPoint.x, (F32)start.y + 2.0f, 0.0f ); verts[1].point.set( (F32)start.x + 11.0f, (F32)midPoint.y - 1.0f, 0.0f ); verts[2].point.set( (F32)start.x + 3.0f, (F32)midPoint.y - 1.0f, 0.0f ); } if(mTextAreaHit == ArrowDown) { verts[3].point.set( (F32)midPoint.x, (F32)(start.y + getExtent().y - 1), 0.0f ); verts[4].point.set( (F32)start.x + 11.0f, (F32)midPoint.y + 3.0f, 0.0f ); verts[5].point.set( (F32)start.x + 3.0f, (F32)midPoint.y + 3.0f, 0.0f ); } else { verts[3].point.set( (F32)midPoint.x, (F32)(start.y + getExtent().y - 2), 0.0f ); verts[4].point.set( (F32)start.x + 11.0f, (F32)midPoint.y + 2.0f, 0.0f ); verts[5].point.set( (F32)start.x + 3.0f, (F32)midPoint.y + 2.0f, 0.0f ); } verts.unlock(); GFX->setVertexBuffer( verts ); GFX->setupGenericShaders(); GFX->drawPrimitive( GFXTriangleList, 0, 2 ); }