1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
// a function to round sharp edges of open and cyclic paths
// written by stefan knorr
path roundedpath(path A, real R, real S = 1)
// create rounded path from path A with radius R and scale S = 1
{
path RoundPath; // returned path
path LocalPath; // local straight subpath
path LocalCirc; // local edge circle for intersection
real LocalTime; // local intersectiontime between . and ..
pair LocalPair; // local point to be added to 'RoundPath'
int len=length(A); // length of given path 'A'
bool PathClosed=cyclic(A); // true, if given path 'A' is cyclic
// initialisation: define first Point of 'RoundPath' as
if (PathClosed) // ? is 'A' cyclic
RoundPath=scale(S)*point(point(A,0)--point(A,1), 0.5); // centerpoint of first straight subpath of 'A'
else
RoundPath=scale(S)*point(A,0); // first point of 'A'
// doing everything between start and end
// create round paths subpath by subpath for every i-th edge
for(int i=1; i < len; ++i)
{
// straight subpath towards i-th edge
LocalPath=point(A,i-1)---point(A,i);
// circle with radius 'R' around i-th edge
LocalCirc=circle(point(A,i),R);
// calculate intersection time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
// define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add straight subpath towards i-th curvature to 'RoundPath'
RoundPath=RoundPath--scale(S)*LocalPair;
}
// straight subpath from i-th edge to (i+1)-th edge
LocalPath=point(A,i)---point(A,i+1);
// calculate intersection-time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
// define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add curvature near i-th edge to 'RoundPath'
RoundPath=RoundPath..scale(S)*LocalPair;
}
}
// final steps to have a correct termination
if(PathClosed) { // Is 'A' cyclic?
// straight subpath towards 0-th edge
LocalPath=point(A,len-1)---point(A,0);
// circle with radius 'R' around 0-th edge
LocalCirc=circle(point(A,0),R);
// calculate intersection-time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
// define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add straight subpath towards 0-th curvature to 'RoundPath'
RoundPath=RoundPath--scale(S)*LocalPair;
}
// straight subpath from 0-th edge to 1st edge
LocalPath=point(A,0)---point(A,1);
// calculate intersection-time between straight subpath and circle
real[] t=intersect(LocalPath, LocalCirc);
if(t.length > 0) {
LocalTime=t[0];
// define intersectionpoint between both paths
LocalPair=point(subpath(LocalPath, 0, LocalTime), 1);
// add curvature near 0-th edge to 'RoundPath' and close path
RoundPath=RoundPath..scale(S)*LocalPair--cycle;
}
} else
RoundPath=RoundPath--scale(S)*point(A,len);
return RoundPath;
}
|