void Stroker::miterJoiner(Stroker* stroker, const Vector& point, const Vector& beforeNormal, const Vector& afterNormal) { Vector realPoint = point; Vector after = afterNormal; Vector before = beforeNormal; stroker->inverseScale_.transform(after); stroker->inverseScale_.transform(before); stroker->inverseScale_.transform(realPoint); DynamicArray<float>* outer = &stroker->outerPoints_; DynamicArray<float>* inner = &stroker->innerPoints_; Winding winding = stroker->determineWinding(before,after); if(winding == cCounterclockwise) { swap(outer,inner); before.invert(); after.invert(); } // Undo perpendiculate Vector prevDir(-before.y_,before.x_); Vector dir(-after.y_,after.x_); Vector intersection; dir.invert(); bool intersectionExists = computeIntersection(realPoint + before, realPoint + after, prevDir,dir, intersection); if(intersectionExists) { float angle = computeAngle(dir,prevDir); float limit = 1/sin(angle/2); if(limit > stroker->miterLimit_) { stroker->bevelJoiner(stroker,point,beforeNormal,afterNormal); return; } stroker->scale_.transform(intersection); stroker->scale_.transform(after); stroker->addPoint(outer,intersection); stroker->addPoint(outer,point + after); stroker->innerJoiner(inner,point,after); } else stroker->bevelJoiner(stroker,point,beforeNormal,afterNormal); }
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), fbp_(new FbpClient()) { ui->setupUi(this); #ifndef BRANDING ui->branding->hide(); #else // Search for BRANDING_LOGO QString brandingLogo( BRANDING_LOGO ); QString prevDir("../"); for(int i = 0; i < 6; ++i) { if( QFile::exists(prevDir.repeated(i) + brandingLogo) ) { brandingLogo.prepend(prevDir.repeated(i)); } } QPixmap logo(brandingLogo); ui->branding->setPixmap(logo); #ifdef BRANDING_AUTOACCEPT ui->autoDownload->setChecked(true); #endif #ifdef BRANDING_WINDOW_TITLE setWindowTitle(BRANDING_WINDOW_TITLE); #endif #endif ui->files->setColumnWidth( 0, 30 ); ui->files->setColumnWidth( 1, 250 ); ui->files->setColumnWidth( 2, 250 ); ui->downloadDir->setText( QDir::homePath() ); connect( ui->chooseDir, SIGNAL( clicked() ), this, SLOT( chooseDir() ) ); connect( fbp_, SIGNAL( fileAdded(int,QString,int) ), this, SLOT( fileAdded(int,QString,int) ) ); connect( fbp_, SIGNAL( fileRemoved(int) ), this, SLOT( fileRemoved(int) ) ); connect( fbp_, SIGNAL( fileProgressChanged(int,int) ), this, SLOT( fileProgressChanged(int,int) ) ); connect( fbp_, SIGNAL(fileOverwriteWarning(int, QString) ), this, SLOT( fileOverwriteWarning(int, QString) ) ); connect( fbp_, SIGNAL( downloadFinished(int, QString) ), this, SLOT( downloadFinished(int, QString) ) ); fbp_->startListening(); }
//==================================================================== // DebugDrawRangePolygon //==================================================================== void CAIDebugRenderer::DrawRangePolygon(const Vec3 polygon[], int nVertices, float fWidth, const ColorB& colorFill, const ColorB& colorOutline, bool bDrawOutline) { static std::vector<Vec3> verts; static std::vector<vtx_idx> tris; static std::vector<Vec3> outline; if (nVertices < 3) return; Vec3 prevDir(polygon[0] - polygon[nVertices - 1]); prevDir.NormalizeSafe(); Vec3 prevNorm(-prevDir.y, prevDir.x, 0.0f); prevNorm.NormalizeSafe(); Vec3 prevPos(polygon[nVertices - 1]); verts.clear(); outline.clear(); const Vec3* li, * linext; const Vec3* liend = polygon + nVertices; for (li = polygon; li != liend ; ++li) { linext = li; ++linext; if (linext == liend) linext = polygon; const Vec3& curPos(*li); const Vec3& nextPos(*linext); Vec3 vDir(nextPos - curPos); Vec3 norm(-vDir.y, vDir.x, 0.0f); norm.NormalizeSafe(); Vec3 mid((prevNorm + norm) * 0.5f); float dmr2 = sqr(mid.x) + sqr(mid.y); if (dmr2 > 0.00001f) mid *= 1.0f / dmr2; float cross = prevDir.x * vDir.y - vDir.x * prevDir.y; outline.push_back(curPos); if (cross < 0.0f) { if (dmr2 * sqr(2.5f) < 1.0f) { // bevel verts.push_back(curPos); verts.push_back(curPos + prevNorm * fWidth); verts.push_back(curPos); verts.push_back(curPos + norm * fWidth); } else { verts.push_back(curPos); verts.push_back(curPos + mid * fWidth); } } else { verts.push_back(curPos); verts.push_back(curPos + mid * fWidth); } prevDir = vDir; prevNorm = norm; prevPos = curPos; } tris.clear(); size_t n = verts.size()/2; for (size_t i = 0; i < n; ++i) { size_t j = (i + 1) % n; tris.push_back(i*2); tris.push_back(j*2); tris.push_back(j*2+1); tris.push_back(i*2); tris.push_back(j*2+1); tris.push_back(i*2+1); } m_pRenderer->GetIRenderAuxGeom()->DrawTriangles(&verts[0], verts.size(), &tris[0], tris.size(), colorFill); if (bDrawOutline) DrawPolyline(&outline[0], outline.size(), true, colorOutline); }
void Curve::computeCurvatureAndOrientation () { const_vertex_iterator v = vertices_begin(), vend = vertices_end(), v2, prevV, v0; Vec2d p0, p1, p2; Vec3r p; p = (*v)->point2d(); p0 = Vec2d(p[0], p[1]); prevV = v; ++v; p = (*v)->point2d(); p1 = Vec2d(p[0], p[1]); Vec2d prevDir(p1 - p0); for (; v! = vend; ++v) { v2 = v; ++v2; if (v2 == vend) break; Vec3r p2 = (*v2)->point2d(); Vec2d BA = p0 - p1; Vec2d BC = p2 - p1; real lba = BA.norm(), lbc = BC.norm(); BA.normalizeSafe(); BC.normalizeSafe(); Vec2d normalCurvature = BA + BC; Vec2d dir = Vec2d(BC - BA); Vec2d normal = Vec2d(-dir[1], dir[0]); normal.normalizeSafe(); real curvature = normalCurvature * normal; if (lba + lbc > MY_EPSILON) curvature /= (0.5 * lba + lbc); if (dir.norm() < MY_EPSILON) dir = 0.1 * prevDir; (*v)->setCurvatureFredo(curvature); (*v)->setDirectionFredo(dir); prevV = v; p0 = p1; p1 = p2; prevDir = dir; prevDir.normalize(); } (*v)->setCurvatureFredo((*prevV)->curvatureFredo()); (*v)->setDirectionFredo((*v)->point2d() - (*prevV)->point2d()); v0 = vertices_begin(); v2 = v0; ++v2; (*v0)->setCurvatureFredo((*v2)->curvatureFredo()); (*v0)->setDirectionFredo((*v2)->point2d() - (*v0)->point2d()); //closed curve case one day... // return; //numerical degeneracy verification... we'll see later const_vertex_iterator vLastReliable = vertices_begin(); v = vertices_begin(); p = (*v)->point2d(); p0 = Vec2d(p[0], p[1]); prevV = v; ++v; p = (*v)->point2d(); p1 = Vec2d(p[0], p[1]); bool isReliable = false; if ((p1 - p0).norm > EPS_CURVA) { vLastReliable = v; isReliable = true; } for (; v != vend; ++v) { v2 = v; ++v2; if (v2 == vend) break; Vec3r p2 = (*v2)->point2d(); Vec2d BA = p0 - p1; Vec2d BC = p2 - p1; real lba = BA.norm(), lbc = BC.norm(); if ((lba + lbc) < EPS_CURVA) { isReliable = false; cerr << "/"; } else { if (!isReliable) { //previous points were not reliable const_vertex_iterator vfix = vLastReliable; ++vfix; for (; vfix != v; ++vfix) { (*vfix)->setCurvatureFredo((*v)->curvatureFredo()); (*vfix)->setDirectionFredo((*v)->directionFredo()); } } isReliable = true; vLastReliable = v; } prevV = v; p0 = p1; p1 = p2; } }