Exemplo n.º 1
0
Geom::Path half_outline_old(Geom::Path const& input, double width, double miter, Inkscape::LineJoinType join = Inkscape::JOIN_BEVEL)
{
    Geom::Path res;
    if (input.size() == 0) return res;

    Geom::Point tang1 = input[0].unitTangentAt(0);
    Geom::Point start = input.initialPoint() + tang1 * width;
    Geom::Path temp;
    Geom::Point tang[2];

    res.setStitching(true);
    temp.setStitching(true);

    res.start(start);

    // Do two curves at a time for efficiency, since the join function needs to know the outgoing curve as well
    const size_t k = (input.back_closed().isDegenerate() && input.closed())
            ?input.size_default()-1:input.size_default();
    for (size_t u = 0; u < k; u += 2) {
        temp.clear();

        offset_curve_old(temp, &input[u], width);

        // on the first run through, there isn't a join
        if (u == 0) {
            res.append(temp);
        } else {
            tangents_old(tang, input[u-1], input[u]);
            outline_join(res, temp, tang[0], tang[1], width, miter, join);
        }

        // odd number of paths
        if (u < k - 1) {
            temp.clear();
            offset_curve_old(temp, &input[u+1], width);
            tangents_old(tang, input[u], input[u+1]);
            outline_join(res, temp, tang[0], tang[1], width, miter, join);
        }
    }

    if (input.closed()) {
        Geom::Curve const &c1 = res.back();
        Geom::Curve const &c2 = res.front();
        temp.clear();
        temp.append(c1);
        Geom::Path temp2;
        temp2.append(c2);
        tangents_old(tang, input.back(), input.front());
        outline_join(temp, temp2, tang[0], tang[1], width, miter, join);
        res.erase(res.begin());
        res.erase_last();
        //
        res.append(temp);
        res.close();
    }

    return res;
}
Exemplo n.º 2
0
std::vector<Geom::Path>
LPEVonKoch::doEffect_path (std::vector<Geom::Path> const & path_in)
{
    using namespace Geom;

    std::vector<Geom::Path> generating_path = generator.get_pathvector();
    
    if (generating_path.size()==0) {
        return path_in;
    }

    //Collect transform matrices.
    Matrix m0;
    Geom::Path refpath = ref_path.get_pathvector().front();
    Point A = refpath.pointAt(0);
    Point B = refpath.pointAt(refpath.size());
    Point u = B-A;
    m0 = Matrix(u[X], u[Y],-u[Y], u[X], A[X], A[Y]);
    
    //FIXME: a path is used as ref instead of 2 points to work around path/point param incompatibility bug.
    //Point u = refB-refA;
    //m0 = Matrix(u[X], u[Y],-u[Y], u[X], refA[X], refA[Y]);
    m0 = m0.inverse();

    std::vector<Matrix> transforms;
    for (unsigned i=0; i<generating_path.size(); i++){
        Matrix m;
        if(generating_path[i].size()==1){
            Point p = generating_path[i].pointAt(0);
            Point u = generating_path[i].pointAt(1)-p;
            m = Matrix(u[X], u[Y],-u[Y], u[X], p[X], p[Y]);
            m = m0*m;
            transforms.push_back(m);
        }else if(generating_path[i].size()>=2){
            Point p = generating_path[i].pointAt(1);
            Point u = generating_path[i].pointAt(2)-p;
            Point v = p-generating_path[i].pointAt(0);
            if (similar_only.get_value()){
                int sign = (u[X]*v[Y]-u[Y]*v[X]>=0?1:-1);
                v[X] = -u[Y]*sign;
                v[Y] =  u[X]*sign;
            }
            m = Matrix(u[X], u[Y],v[X], v[Y], p[X], p[Y]);
            m = m0*m;
            transforms.push_back(m);
        }
    }

    if (transforms.size()==0){
        return path_in;
    }

    //Do nothing if the output is too complex... 
    int path_in_complexity = 0;
    for (unsigned k = 0; k < path_in.size(); k++){
            path_in_complexity+=path_in[k].size();
    }    
    double complexity = pow(transforms.size(),nbgenerations)*path_in_complexity;
    if (drawall.get_value()){
        int k = transforms.size();
        if(k>1){
            complexity = (pow(k,nbgenerations+1)-1)/(k-1)*path_in_complexity;
        }else{
            complexity = nbgenerations*k*path_in_complexity;
        }
    }else{
        complexity = pow(transforms.size(),nbgenerations)*path_in_complexity;
    }
    if (complexity > double(maxComplexity)){
        g_warning("VonKoch lpe's output too complex. Effect bypassed.");
        return path_in;
    }

    //Generate path:
    std::vector<Geom::Path> pathi = path_in;
    std::vector<Geom::Path> path_out = path_in;
    
    for (unsigned i = 0; i<nbgenerations; i++){
        if (drawall.get_value()){
            path_out =  path_in;
            complexity = path_in_complexity;
        }else{
            path_out = std::vector<Geom::Path>();
            complexity = 0;
        }
        for (unsigned j = 0; j<transforms.size(); j++){
            for (unsigned k = 0; k<pathi.size() && complexity < maxComplexity; k++){
                path_out.push_back(pathi[k]*transforms[j]); 
                complexity+=pathi[k].size();
            }
        }
        pathi = path_out;
    }
    return path_out;
}