当前位置:网站首页>[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

边栏推荐
- 【日常训练】513. 找树左下角的值
- English语法_形容词比较级 - 3级变化
- Wechat applet - Global Monitoring of certain attribute changes of GlobalData, such as monitoring of network state switching
- Business logic design of physical warehouse and virtual warehouse in middle inventory
- mysql 函数
- 关于监督
- 微信小程序 - 全局监听globalData的某个属性变化,例如监听网络状态切换
- redux Actions may not have an undefined “type“ property. Have you misspelled a constant?
- 疫情下的传媒产业,小程序生态驱动数字化转型探索
- /bin/sh no such file or directory问题
猜你喜欢

【系统】右键桌面图标,转圈后,资源管理器就崩溃,桌面就重新刷新

How to view native IP

leetcode - 572. A subtree of another tree

cmder

Some difficulties in making web pages

【STL】顺序容器之deque用法总结

How to realize video call and live interaction in a small program when live broadcasting is so popular?

QT method of compiling projects using multithreading

Open source ecology 𞓜 super practical open source license basic knowledge literacy post (Part 2)

Influence of steam education on domestic college students
随机推荐
XML DTD record
【BULL中文文档】用于在 NodeJS 中处理分布式作业和消息的队列包
Haas 506 2.0 Tutoriel de développement - bibliothèque de composants avancés - modem. SMS (ne prend en charge que les versions supérieures à 2,2)
30 data visualization tips that can not be ignored
Swagger3 integrates oauth2 authentication token
mysql 基础查询
Termux
[QT] basic learning notes
haas506 2.0开发教程-高级组件库-modem.sim(仅支持2.2以上版本)
C语言运算符优先级口诀
Measurement principle and thickness measurement mode of spectral confocal
[graduation season · advanced technology Er] it's my choice. I have to walk on my knees
二叉树的遍历及相关知识
Anti chicken soup speech
ssm + ftp +ueditor
Open source oauth2 framework for SSO single sign on
Qt 中 QVariant 使用总结
cmder
WPF Command指令和INotifyPropertyChanged
Topic35——34. Find the first and last positions of elements in a sorted array