format
This commit is contained in:
parent
5b9e5ac9c1
commit
8a38e0d9e9
1 changed files with 133 additions and 119 deletions
|
|
@ -519,13 +519,33 @@ func splitBezierCurve(p1, p2, p3, p4 *geo.Point, t0, t1 float64) (geo.Point, geo
|
||||||
return q1, q2, q3, q4
|
return q1, q2, q3, q4
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitPath(path string, percentage float64) (string, string) {
|
func addToPath(path *string, pathType *string, i int, pathData []string) int {
|
||||||
var sumPathLens, curPathLen, x, y, pathLength float64
|
|
||||||
var prevPosition geo.Point
|
|
||||||
var path1, path2 string
|
|
||||||
var increment int
|
var increment int
|
||||||
|
|
||||||
pathData := strings.Split(path, " ")
|
switch *pathType {
|
||||||
|
case "M":
|
||||||
|
*path += fmt.Sprintf("M %s %s ", pathData[i+1], pathData[i+2])
|
||||||
|
increment = 3
|
||||||
|
case "L":
|
||||||
|
*path += fmt.Sprintf("L %s %s ", pathData[i+1], pathData[i+2])
|
||||||
|
increment = 3
|
||||||
|
case "C":
|
||||||
|
*path += fmt.Sprintf("C %s %s %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4], pathData[i+5], pathData[i+6])
|
||||||
|
increment = 7
|
||||||
|
case "S":
|
||||||
|
*path += fmt.Sprintf("S %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4])
|
||||||
|
increment = 5
|
||||||
|
default:
|
||||||
|
panic(fmt.Sprintf("unknown svg path command \"%s\"", pathData[i]))
|
||||||
|
}
|
||||||
|
|
||||||
|
return increment
|
||||||
|
}
|
||||||
|
|
||||||
|
func pathLength(pathData []string) float64 {
|
||||||
|
var x, y, pathLength float64
|
||||||
|
var increment int
|
||||||
|
var prevPosition geo.Point
|
||||||
|
|
||||||
for i := 0; i < len(pathData); {
|
for i := 0; i < len(pathData); {
|
||||||
switch pathData[i] {
|
switch pathData[i] {
|
||||||
|
|
@ -559,19 +579,31 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
panic(fmt.Sprintf("unknown svg path command \"%s\"", pathData[i]))
|
panic(fmt.Sprintf("unknown svg path command \"%s\"", pathData[i]))
|
||||||
}
|
}
|
||||||
|
|
||||||
prevPosition = geo.Point{X: x, Y: y};
|
prevPosition = geo.Point{X: x, Y: y}
|
||||||
i += increment;
|
i += increment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pathLength
|
||||||
|
}
|
||||||
|
|
||||||
|
func splitPath(path string, percentage float64) (string, string) {
|
||||||
|
var sumPathLens, curPathLen, x, y float64
|
||||||
|
var prevPosition geo.Point
|
||||||
|
var path1, path2 string
|
||||||
|
var increment int
|
||||||
|
|
||||||
|
pathData := strings.Split(path, " ")
|
||||||
|
pathLen := pathLength(pathData)
|
||||||
|
|
||||||
i := 0
|
i := 0
|
||||||
|
|
||||||
for ; i < len(pathData); {
|
for i < len(pathData) {
|
||||||
switch pathData[i] {
|
switch pathData[i] {
|
||||||
case "M":
|
case "M":
|
||||||
x, _ = strconv.ParseFloat(pathData[i+1], 64)
|
x, _ = strconv.ParseFloat(pathData[i+1], 64)
|
||||||
y, _ = strconv.ParseFloat(pathData[i+2], 64)
|
y, _ = strconv.ParseFloat(pathData[i+2], 64)
|
||||||
|
|
||||||
if sumPathLens + curPathLen < pathLength * percentage {
|
if sumPathLens+curPathLen < pathLen*percentage {
|
||||||
path1 += fmt.Sprintf("M %s %s ", pathData[i+1], pathData[i+2])
|
path1 += fmt.Sprintf("M %s %s ", pathData[i+1], pathData[i+2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -582,7 +614,7 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
|
|
||||||
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
||||||
|
|
||||||
if sumPathLens + curPathLen < pathLength * percentage {
|
if sumPathLens+curPathLen < pathLen*percentage {
|
||||||
path1 += fmt.Sprintf("L %s %s ", pathData[i+1], pathData[i+2])
|
path1 += fmt.Sprintf("L %s %s ", pathData[i+1], pathData[i+2])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -593,8 +625,8 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
|
|
||||||
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
||||||
|
|
||||||
if sumPathLens + curPathLen < pathLength * percentage {
|
if sumPathLens+curPathLen < pathLen*percentage {
|
||||||
path1 += fmt.Sprintf("C %s %s %s %s %s %s ", pathData[i + 1], pathData[i + 2], pathData[i + 3], pathData[i + 4], pathData[i + 5], pathData[i + 6]);
|
path1 += fmt.Sprintf("C %s %s %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4], pathData[i+5], pathData[i+6])
|
||||||
}
|
}
|
||||||
|
|
||||||
increment = 7
|
increment = 7
|
||||||
|
|
@ -604,7 +636,7 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
|
|
||||||
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
curPathLen = geo.EuclideanDistance(prevPosition.X, prevPosition.Y, x, y)
|
||||||
|
|
||||||
if sumPathLens + curPathLen < pathLength * percentage {
|
if sumPathLens+curPathLen < pathLen*percentage {
|
||||||
path1 += fmt.Sprintf("S %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4])
|
path1 += fmt.Sprintf("S %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -615,11 +647,10 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
|
|
||||||
sumPathLens += curPathLen
|
sumPathLens += curPathLen
|
||||||
|
|
||||||
if sumPathLens >= pathLength * percentage {
|
if sumPathLens >= pathLen*percentage {
|
||||||
t := (pathLength * percentage - sumPathLens + curPathLen) / curPathLen
|
t := (pathLen*percentage - sumPathLens + curPathLen) / curPathLen
|
||||||
fmt.Println(t)
|
|
||||||
|
|
||||||
switch(pathData[i]) {
|
switch pathData[i] {
|
||||||
case "L":
|
case "L":
|
||||||
path1 += fmt.Sprintf("L %f %f ", (x-prevPosition.X)*t+prevPosition.X, (y-prevPosition.Y)*t+prevPosition.Y)
|
path1 += fmt.Sprintf("L %f %f ", (x-prevPosition.X)*t+prevPosition.X, (y-prevPosition.Y)*t+prevPosition.Y)
|
||||||
path2 += fmt.Sprintf("M %f %f L %f %f ", (x-prevPosition.X)*t+prevPosition.X, (y-prevPosition.Y)*t+prevPosition.Y, x, y)
|
path2 += fmt.Sprintf("M %f %f L %f %f ", (x-prevPosition.X)*t+prevPosition.X, (y-prevPosition.Y)*t+prevPosition.Y, x, y)
|
||||||
|
|
@ -628,22 +659,19 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
h1y, _ := strconv.ParseFloat(pathData[i+2], 64)
|
h1y, _ := strconv.ParseFloat(pathData[i+2], 64)
|
||||||
h2x, _ := strconv.ParseFloat(pathData[i+3], 64)
|
h2x, _ := strconv.ParseFloat(pathData[i+3], 64)
|
||||||
h2y, _ := strconv.ParseFloat(pathData[i+4], 64)
|
h2y, _ := strconv.ParseFloat(pathData[i+4], 64)
|
||||||
p1x, _ := strconv.ParseFloat(pathData[i + 5], 64)
|
|
||||||
p1y, _ := strconv.ParseFloat(pathData[i + 6], 64)
|
|
||||||
|
|
||||||
heading1 := geo.Point{X: h1x, Y: h1y}
|
heading1 := geo.Point{X: h1x, Y: h1y}
|
||||||
heading2 := geo.Point{X: h2x, Y: h2y}
|
heading2 := geo.Point{X: h2x, Y: h2y}
|
||||||
nextPoint := geo.Point{X: p1x, Y: p1y}
|
nextPoint := geo.Point{X: x, Y: y}
|
||||||
|
|
||||||
q1, q2, q3, q4 := splitBezierCurve(&prevPosition, &heading1, &heading2, &nextPoint, 0, 0.5)
|
q1, q2, q3, q4 := splitBezierCurve(&prevPosition, &heading1, &heading2, &nextPoint, 0, 0.5)
|
||||||
|
path1 += fmt.Sprintf("C %f %f %f %f %f %f ", q2.X, q2.Y, q3.X, q3.Y, q4.X, q4.Y)
|
||||||
path1 += fmt.Sprintf("C %f %f %f %f %f %f ", q2.X, q2.Y, q3.X, q3.Y, q4.X, q4.Y);
|
|
||||||
|
|
||||||
q1, q2, q3, q4 = splitBezierCurve(&prevPosition, &heading1, &heading2, &nextPoint, 0.5, 1)
|
q1, q2, q3, q4 = splitBezierCurve(&prevPosition, &heading1, &heading2, &nextPoint, 0.5, 1)
|
||||||
|
path2 += fmt.Sprintf("M %f %f C %f %f %f %f %f %f ", q1.X, q1.Y, q2.X, q2.Y, q3.X, q3.Y, q4.X, q4.Y)
|
||||||
path2 += fmt.Sprintf("M %f %f C %f %f %f %f %f %f ", q1.X, q1.Y, q2.X, q2.Y, q3.X, q3.Y, q4.X, q4.Y);
|
|
||||||
|
|
||||||
case "S":
|
case "S":
|
||||||
|
// Skip S curves because they are shorter and we can split along the connection to the next path instead
|
||||||
path1 += fmt.Sprintf("S %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4])
|
path1 += fmt.Sprintf("S %s %s %s %s ", pathData[i+1], pathData[i+2], pathData[i+3], pathData[i+4])
|
||||||
path2 += fmt.Sprintf("M %s %s ", pathData[i+3], pathData[i+4])
|
path2 += fmt.Sprintf("M %s %s ", pathData[i+3], pathData[i+4])
|
||||||
default:
|
default:
|
||||||
|
|
@ -659,23 +687,9 @@ func splitPath(path string, percentage float64) (string, string) {
|
||||||
prevPosition = geo.Point{X: x, Y: y}
|
prevPosition = geo.Point{X: x, Y: y}
|
||||||
}
|
}
|
||||||
|
|
||||||
for ; i < len(pathData); {
|
for i < len(pathData) {
|
||||||
switch pathData[i] {
|
pathType := pathData[i]
|
||||||
case "M":
|
increment := addToPath(&path2, &pathType, i, pathData)
|
||||||
path2 += fmt.Sprintf("M %s %s ", pathData[i + 1], pathData[i + 2])
|
|
||||||
increment = 3
|
|
||||||
case "L":
|
|
||||||
path2 += fmt.Sprintf("L %s %s ", pathData[i + 1], pathData[i + 2])
|
|
||||||
increment = 3
|
|
||||||
case "C":
|
|
||||||
path2 += fmt.Sprintf("C %s %s %s %s %s %s ", pathData[i + 1], pathData[i + 2], pathData[i + 3], pathData[i + 4], pathData[i + 5], pathData[i + 6]);
|
|
||||||
increment = 7
|
|
||||||
case "S":
|
|
||||||
path2 += fmt.Sprintf("S %s %s %s %s ", pathData[i + 1], pathData[i + 2], pathData[i + 3], pathData[i + 4])
|
|
||||||
increment = 5
|
|
||||||
default:
|
|
||||||
panic(fmt.Sprintf("unknown svg path command \"%s\"", pathData[i]))
|
|
||||||
}
|
|
||||||
|
|
||||||
i += increment
|
i += increment
|
||||||
}
|
}
|
||||||
|
|
@ -769,7 +783,7 @@ func drawConnection(writer io.Writer, labelMaskID string, connection d2target.Co
|
||||||
pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask)
|
pathEl.Attributes = fmt.Sprintf("%s%s%s", markerStart, markerEnd, mask)
|
||||||
fmt.Fprint(writer, pathEl.Render())
|
fmt.Fprint(writer, pathEl.Render())
|
||||||
} else {
|
} else {
|
||||||
path1, path2 := splitPath(path, 0.5);
|
path1, path2 := splitPath(path, 0.5)
|
||||||
|
|
||||||
pathEl1 := d2themes.NewThemableElement("path")
|
pathEl1 := d2themes.NewThemableElement("path")
|
||||||
pathEl1.D = path1
|
pathEl1.D = path1
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue