当前位置:网站首页>[project training] multi segment line expanded to parallel line

[project training] multi segment line expanded to parallel line

2022-06-23 06:56:00 From winter

The transformation of lines is easy , By increasing the position of keys , Its svg The format will connect key points in sequence .

Key points are divided into transparent and opaque , Both can be dragged , Transparent keys cross with opaque keys , And the transparent key is at the midpoint of its adjacent opaque key . The endpoint is always an opaque key

 

As you drag keys , It is divided into endpoint and internal key points . If endpoint , You can change the coordinates directly , If it is an internal key point , After changing the key point, two more internal key points will appear , The new key appears at the midpoint .

And when you drag an internal key , It may become a straight line with its adjacent left and right keys , At this time, delete it .

std::string res = "M " + std::to_string(startPoint->getX()) + " "
                              + std::to_string(startPoint->getY()) + " ";

            for (int i = 2; i < (int) pointList.size(); i += 2) {
                res += "L " + std::to_string(pointList[i]->getX()) + " " + std::to_string(pointList[i]->getY()) + " ";
            }
            return res;

Expand lines to parallel lines , First, record the shape of the line , Then expand outward .

Mainly looking for various turning points , Then connect in sequence , Both the starting point and the ending point are special turning points
In this way, each line segment has a corresponding 2 The equation describing two equidistant parallel lines , Similar 2 Equidistant parallel lines have and only 1 A point of intersection , It is the turning point on the corresponding equidistant parallel line .

std::vector<Lewzen::Point2D> Line::offsetCoords(std::vector<Lewzen::Point2D> coords, double offset) {
        std::vector<Lewzen::Point2D> path;

        int N = coords.size() - 1;
        int max = N;
        double mi, mi1, li, li1, ri, ri1, si, si1, Xi1, Yi1;
        Lewzen::Point2D p0(0, 0), p1(0, 0), p2(0, 0);
        int isClosed = (coords[0].get_x() == coords[N].get_x() &&
                        coords[0].get_y() == coords[N].get_y());
        if (!isClosed) {
            p0 = coords[0];
            p1 = coords[1];
            p2 = Lewzen::Point2D(p0.get_x() + (p1.get_y() - p0.get_y()) / dist2d(p0, p1) * offset,
                                 p0.get_y() - (p1.get_x() - p0.get_x()) / dist2d(p0, p1) * offset);

            path.push_back(p2);
            coords.push_back(coords[N]);
            N++;
            max--;
        }
        for (int i = 0; i < max; i++) {
            p0 = coords[i];
            p1 = coords[(i + 1) % N];
            p2 = coords[(i + 2) % N];
            mi = (p1.get_y() - p0.get_y()) / (p1.get_x() - p0.get_x());
            mi1 = (p2.get_y() - p1.get_y()) / (p2.get_x() - p1.get_x());
            // Prevent alignements
            if (fabs(mi - mi1) > 1e-10) {
//            li = Math.sqrt((p1[0] - p0[0])*(p1[0] - p0[0])+(p1[1] - p0[1])*(p1[1] - p0[1]));
//            li1 = Math.sqrt((p2[0] - p1[0])*(p2[0] - p1[0])+(p2[1] - p1[1])*(p2[1] - p1[1]));
                li = dist2d(p1, p0);
                li1 = dist2d(p2, p1);
                ri = p0.get_x() + offset * (p1.get_y() - p0.get_y()) / li;
                ri1 = p1.get_x() + offset * (p2.get_y() - p1.get_y()) / li1;
                si = p0.get_y() - offset * (p1.get_x() - p0.get_x()) / li;
                si1 = p1.get_y() - offset * (p2.get_x() - p1.get_x()) / li1;
                Xi1 = (mi1 * ri1 - mi * ri + si - si1) / (mi1 - mi);
                Yi1 = (mi * mi1 * (ri1 - ri) + mi1 * si - mi * si1) / (mi1 - mi);
                // Correction for vertical lines
                if (p1.get_x() - p0.get_x() == 0) {
                    Xi1 = p1.get_x() + offset * (p1.get_y() - p0.get_y()) / fabs(p1.get_y() - p0.get_y());
                    Yi1 = mi1 * Xi1 - mi1 * ri1 + si1;
                }
                if (p2.get_x() - p1.get_x() == 0) {
                    Xi1 = p2.get_x() + offset * (p2.get_y() - p1.get_y()) / fabs(p2.get_y() - p1.get_y());
                    Yi1 = mi * Xi1 - mi * ri + si;
                }
                path.push_back(Lewzen::Point2D(Xi1, Yi1));
            }
        }
        if (isClosed) {
            path.push_back(path[0]);
        } else {
            coords.pop_back();
            p0 = coords[coords.size() - 1];
            p1 = coords[coords.size() - 2];
            p2 = Lewzen::Point2D(p0.get_x() - (p1.get_y() - p0.get_y()) / dist2d(p0, p1) * offset,
                                 p0.get_y() + (p1.get_x() - p0.get_x()) / dist2d(p0, p1) * offset);
            path.push_back(p2);
        }
        return path;
    }

The expanded shape of a polyline

原网站

版权声明
本文为[From winter]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/174/202206230559225744.html