This commit is contained in:
Mayank Mohapatra 2025-03-08 10:56:38 +00:00
parent adf3c651e2
commit d594af3f4a
5 changed files with 242 additions and 236 deletions

View file

@ -14,7 +14,7 @@ import (
const ( const (
MIN_RADIUS = 200 MIN_RADIUS = 200
PADDING = 20 PADDING = 20
MIN_SEGMENT_LEN = 10 MIN_SEGMENT_LEN = 10.0 // Changed to float64
ARC_STEPS = 100 ARC_STEPS = 100
) )
@ -41,22 +41,12 @@ func Layout(ctx context.Context, g *d2graph.Graph, layout d2graph.LayoutGraph) e
func calculateRadius(objects []*d2graph.Object) float64 { func calculateRadius(objects []*d2graph.Object) float64 {
numObjects := float64(len(objects)) numObjects := float64(len(objects))
if numObjects == 0 { maxSize := 0.0
return MIN_RADIUS
}
maxDiagonal := 0.0
for _, obj := range objects { for _, obj := range objects {
// Calculate the diagonal of the object's bounding box size := math.Max(obj.Box.Width, obj.Box.Height)
diagonal := math.Sqrt(obj.Box.Width*obj.Box.Width + obj.Box.Height*obj.Box.Height) maxSize = math.Max(maxSize, size)
if diagonal > maxDiagonal {
maxDiagonal = diagonal
}
} }
minRadius := (maxSize/2.0 + PADDING) / math.Sin(math.Pi/numObjects)
// Required chord length: sum of two radii (maxDiagonal/2) + padding
requiredChordLength := maxDiagonal + PADDING
minRadius := requiredChordLength / (2 * math.Sin(math.Pi/numObjects))
return math.Max(minRadius, MIN_RADIUS) return math.Max(minRadius, MIN_RADIUS)
} }
@ -83,14 +73,27 @@ func createCircularArc(edge *d2graph.Edge) {
srcCenter := edge.Src.Center() srcCenter := edge.Src.Center()
dstCenter := edge.Dst.Center() dstCenter := edge.Dst.Center()
// Calculate the angle of each object from the origin (0,0)
srcAngle := math.Atan2(srcCenter.Y, srcCenter.X) srcAngle := math.Atan2(srcCenter.Y, srcCenter.X)
dstAngle := math.Atan2(dstCenter.Y, dstCenter.X) dstAngle := math.Atan2(dstCenter.Y, dstCenter.X)
// Determine the shortest arc direction
if dstAngle < srcAngle { if dstAngle < srcAngle {
dstAngle += 2 * math.Pi if srcAngle - dstAngle > math.Pi {
dstAngle += 2 * math.Pi
}
} else {
if dstAngle - srcAngle > math.Pi {
srcAngle += 2 * math.Pi
}
} }
arcRadius := math.Hypot(srcCenter.X, srcCenter.Y) // Use the average radius for a smooth circular arc
srcRadius := math.Hypot(srcCenter.X, srcCenter.Y)
dstRadius := math.Hypot(dstCenter.X, dstCenter.Y)
arcRadius := (srcRadius + dstRadius) / 2
// Create a perfectly circular arc with more points for smoothness
path := make([]*geo.Point, 0, ARC_STEPS+1) path := make([]*geo.Point, 0, ARC_STEPS+1)
for i := 0; i <= ARC_STEPS; i++ { for i := 0; i <= ARC_STEPS; i++ {
t := float64(i) / float64(ARC_STEPS) t := float64(i) / float64(ARC_STEPS)
@ -99,27 +102,31 @@ func createCircularArc(edge *d2graph.Edge) {
y := arcRadius * math.Sin(angle) y := arcRadius * math.Sin(angle)
path = append(path, geo.NewPoint(x, y)) path = append(path, geo.NewPoint(x, y))
} }
// Ensure the path starts and ends at the centers
path[0] = srcCenter path[0] = srcCenter
path[len(path)-1] = dstCenter path[len(path)-1] = dstCenter
// Clamp endpoints to the boundaries of the source and destination boxes. // Find precise intersection points with object boundaries
_, newSrc := clampPointOutsideBox(edge.Src.Box, path, 0) _, newSrc := clampPointOutsideBox(edge.Src.Box, path, 0)
_, newDst := clampPointOutsideBoxReverse(edge.Dst.Box, path, len(path)-1) _, newDst := clampPointOutsideBoxReverse(edge.Dst.Box, path, len(path)-1)
path[0] = newSrc path[0] = newSrc
path[len(path)-1] = newDst path[len(path)-1] = newDst
// Trim redundant path points that fall inside node boundaries. // Trim points that are inside the objects' boxes
path = trimPathPoints(path, edge.Src.Box) path = trimPathPoints(path, edge.Src.Box)
path = trimPathPoints(path, edge.Dst.Box) path = trimPathPoints(path, edge.Dst.Box)
edge.Route = path edge.Route = path
edge.IsCurve = true edge.IsCurve = true
// Adjust the final segment for proper arrow rendering
if len(edge.Route) >= 2 { if len(edge.Route) >= 2 {
lastIndex := len(edge.Route) - 1 lastIndex := len(edge.Route) - 1
lastPoint := edge.Route[lastIndex] lastPoint := edge.Route[lastIndex]
secondLastPoint := edge.Route[lastIndex-1] secondLastPoint := edge.Route[lastIndex-1]
// Calculate tangent at the intersection point (perpendicular to radius)
tangentX := -lastPoint.Y tangentX := -lastPoint.Y
tangentY := lastPoint.X tangentY := lastPoint.X
mag := math.Hypot(tangentX, tangentY) mag := math.Hypot(tangentX, tangentY)
@ -127,8 +134,8 @@ func createCircularArc(edge *d2graph.Edge) {
tangentX /= mag tangentX /= mag
tangentY /= mag tangentY /= mag
} }
const MIN_SEGMENT_LEN = 4.159
// Check if final segment needs adjustment
dx := lastPoint.X - secondLastPoint.X dx := lastPoint.X - secondLastPoint.X
dy := lastPoint.Y - secondLastPoint.Y dy := lastPoint.Y - secondLastPoint.Y
segLength := math.Hypot(dx, dy) segLength := math.Hypot(dx, dy)
@ -136,9 +143,8 @@ func createCircularArc(edge *d2graph.Edge) {
currentDirX := dx / segLength currentDirX := dx / segLength
currentDirY := dy / segLength currentDirY := dy / segLength
// Check if we need to adjust the direction // If segment is too short or not aligned with the tangent
if segLength < MIN_SEGMENT_LEN || (currentDirX*tangentX+currentDirY*tangentY) < 0.999 { if segLength < MIN_SEGMENT_LEN || (currentDirX*tangentX+currentDirY*tangentY) < 0.99 {
// Create new point along tangent direction
adjustLength := MIN_SEGMENT_LEN // Now float64 adjustLength := MIN_SEGMENT_LEN // Now float64
if segLength >= MIN_SEGMENT_LEN { if segLength >= MIN_SEGMENT_LEN {
adjustLength = segLength // Both are float64 now adjustLength = segLength // Both are float64 now
@ -335,4 +341,4 @@ func positionLabelsIcons(obj *d2graph.Object) {
} }
} }
} }
} }

View file

@ -1408,8 +1408,8 @@
"y": -37.47600173950195 "y": -37.47600173950195
}, },
{ {
"x": 196.5659942626953, "x": 195.6020050048828,
"y": -37.10100173950195 "y": -42.86199951171875
}, },
{ {
"x": 197.2519989013672, "x": 197.2519989013672,
@ -1772,8 +1772,8 @@
"y": 197.53700256347656 "y": 197.53700256347656
}, },
{ {
"x": 30.621999740600586, "x": 36.4109992980957,
"y": 197.6790008544922 "y": 196.90499877929688
}, },
{ {
"x": 26.5, "x": 26.5,
@ -2136,8 +2136,8 @@
"y": 37.47600173950195 "y": 37.47600173950195
}, },
{ {
"x": -196.5659942626953, "x": -195.6020050048828,
"y": 37.10100173950195 "y": 42.86199951171875
}, },
{ {
"x": -197.2519989013672, "x": -197.2519989013672,
@ -2516,8 +2516,8 @@
"y": 111.8030014038086 "y": 111.8030014038086
}, },
{ {
"x": 702.8259887695312, "x": 704.7830200195312,
"y": 113.08100128173828 "y": 107.5770034790039
}, },
{ {
"x": 701.4329833984375, "x": 701.4329833984375,
@ -2880,8 +2880,8 @@
"y": 186.90899658203125 "y": 186.90899658203125
}, },
{ {
"x": 366.4079895019531, "x": 370.2919921875,
"y": 186.1060028076172 "y": 190.46800231933594
}, },
{ {
"x": 363.6419982910156, "x": 363.6419982910156,
@ -3284,8 +3284,8 @@
"y": 196.45700073242188 "y": 196.45700073242188
}, },
{ {
"x": 1003.2860107421875, "x": 1008.4110107421875,
"y": 197.53700256347656 "y": 196.89300537109375
}, },
{ {
"x": 998.5, "x": 998.5,
@ -3596,8 +3596,8 @@
"y": -135.375 "y": -135.375
}, },
{ {
"x": 1231.5989990234375, "x": 1227.7139892578125,
"y": -136.1060028076172 "y": -140.46800231933594
}, },
{ {
"x": 1234.364990234375, "x": 1234.364990234375,
@ -3896,8 +3896,8 @@
"y": 63.79100036621094 "y": 63.79100036621094
}, },
{ {
"x": 1274.833984375, "x": 1276.7900390625,
"y": 63.08100128173828 "y": 57.57699966430664
}, },
{ {
"x": 1273.43994140625, "x": 1273.43994140625,
@ -4208,8 +4208,8 @@
"y": 197.85400390625 "y": 197.85400390625
}, },
{ {
"x": 1116.1199951171875, "x": 1121.907958984375,
"y": 197.6060028076172 "y": 196.8179931640625
}, },
{ {
"x": 1112, "x": 1112,
@ -4520,8 +4520,8 @@
"y": 135.375 "y": 135.375
}, },
{ {
"x": 938.4000244140625, "x": 942.2849731445312,
"y": 136.1060028076172 "y": 140.46800231933594
}, },
{ {
"x": 935.6339721679688, "x": 935.6339721679688,
@ -4820,8 +4820,8 @@
"y": -63.79100036621094 "y": -63.79100036621094
}, },
{ {
"x": 895.1649780273438, "x": 893.208984375,
"y": -63.08100128173828 "y": -57.57699966430664
}, },
{ {
"x": 896.5590209960938, "x": 896.5590209960938,
@ -5160,8 +5160,8 @@
"y": -78.54499816894531 "y": -78.54499816894531
}, },
{ {
"x": 1718.126953125, "x": 1715.3590087890625,
"y": -78.46499633789062 "y": -83.60800170898438
}, },
{ {
"x": 1720.0989990234375, "x": 1720.0989990234375,
@ -5492,8 +5492,8 @@
"y": 156.90899658203125 "y": 156.90899658203125
}, },
{ {
"x": 1690.9420166015625, "x": 1694.9930419921875,
"y": 155.73899841308594 "y": 151.53199768066406
}, },
{ {
"x": 1688.0570068359375, "x": 1688.0570068359375,
@ -5832,8 +5832,8 @@
"y": 199.88099670410156 "y": 199.88099670410156
}, },
{ {
"x": 1457.1510009765625, "x": 1462.3590087890625,
"y": 200.20199584960938 "y": 202.8470001220703
}, },
{ {
"x": 1453.4420166015625, "x": 1453.4420166015625,
@ -6160,8 +6160,8 @@
"y": -5.065999984741211 "y": -5.065999984741211
}, },
{ {
"x": 1345.489013671875, "x": 1344.64794921875,
"y": -4.686999797821045 "y": 1.0920000076293945
}, },
{ {
"x": 1346.0880126953125, "x": 1346.0880126953125,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB

View file

@ -1408,8 +1408,8 @@
"y": -25.47599983215332 "y": -25.47599983215332
}, },
{ {
"x": 208.5659942626953, "x": 207.6020050048828,
"y": -25.10099983215332 "y": -30.86199951171875
}, },
{ {
"x": 209.2519989013672, "x": 209.2519989013672,
@ -1772,8 +1772,8 @@
"y": 209.53700256347656 "y": 209.53700256347656
}, },
{ {
"x": 42.62200164794922, "x": 48.4109992980957,
"y": 209.6790008544922 "y": 208.90499877929688
}, },
{ {
"x": 38.5, "x": 38.5,
@ -2136,8 +2136,8 @@
"y": 49.47600173950195 "y": 49.47600173950195
}, },
{ {
"x": -184.5659942626953, "x": -183.6020050048828,
"y": 49.10100173950195 "y": 54.86199951171875
}, },
{ {
"x": -185.2519989013672, "x": -185.2519989013672,
@ -2516,8 +2516,8 @@
"y": 123.8030014038086 "y": 123.8030014038086
}, },
{ {
"x": 675.3259887695312, "x": 677.2830200195312,
"y": 125.08100128173828 "y": 119.5770034790039
}, },
{ {
"x": 673.9329833984375, "x": 673.9329833984375,
@ -2880,8 +2880,8 @@
"y": 198.90899658203125 "y": 198.90899658203125
}, },
{ {
"x": 338.9079895019531, "x": 342.7919921875,
"y": 198.1060028076172 "y": 202.46800231933594
}, },
{ {
"x": 336.1419982910156, "x": 336.1419982910156,
@ -3284,8 +3284,8 @@
"y": 208.45700073242188 "y": 208.45700073242188
}, },
{ {
"x": 936.197021484375, "x": 941.3209838867188,
"y": 209.53700256347656 "y": 208.89300537109375
}, },
{ {
"x": 931.4099731445312, "x": 931.4099731445312,
@ -3596,8 +3596,8 @@
"y": -123.375 "y": -123.375
}, },
{ {
"x": 1124.509033203125, "x": 1120.625,
"y": -124.10600280761719 "y": -128.46800231933594
}, },
{ {
"x": 1127.2750244140625, "x": 1127.2750244140625,
@ -3896,8 +3896,8 @@
"y": 75.79100036621094 "y": 75.79100036621094
}, },
{ {
"x": 1167.7440185546875, "x": 1169.7010498046875,
"y": 75.08100128173828 "y": 69.5770034790039
}, },
{ {
"x": 1166.3509521484375, "x": 1166.3509521484375,
@ -4208,8 +4208,8 @@
"y": 209.85400390625 "y": 209.85400390625
}, },
{ {
"x": 1009.031005859375, "x": 1014.8179931640625,
"y": 209.6060028076172 "y": 208.8179931640625
}, },
{ {
"x": 1004.9099731445312, "x": 1004.9099731445312,
@ -4520,8 +4520,8 @@
"y": 147.375 "y": 147.375
}, },
{ {
"x": 831.3099975585938, "x": 835.1950073242188,
"y": 148.1060028076172 "y": 152.46800231933594
}, },
{ {
"x": 828.5449829101562, "x": 828.5449829101562,
@ -4820,8 +4820,8 @@
"y": -51.79100036621094 "y": -51.79100036621094
}, },
{ {
"x": 788.0750122070312, "x": 786.1190185546875,
"y": -51.08100128173828 "y": -45.57699966430664
}, },
{ {
"x": 789.468994140625, "x": 789.468994140625,
@ -5160,8 +5160,8 @@
"y": -67.4469985961914 "y": -67.4469985961914
}, },
{ {
"x": 1571.447998046875, "x": 1568.678955078125,
"y": -67.36699676513672 "y": -72.51000213623047
}, },
{ {
"x": 1573.4189453125, "x": 1573.4189453125,
@ -5492,8 +5492,8 @@
"y": 168.0070037841797 "y": 168.0070037841797
}, },
{ {
"x": 1544.261962890625, "x": 1548.31396484375,
"y": 166.83799743652344 "y": 162.6300048828125
}, },
{ {
"x": 1541.376953125, "x": 1541.376953125,
@ -5832,8 +5832,8 @@
"y": 210.97900390625 "y": 210.97900390625
}, },
{ {
"x": 1310.470947265625, "x": 1315.678955078125,
"y": 211.30099487304688 "y": 213.94500732421875
}, },
{ {
"x": 1306.762939453125, "x": 1306.762939453125,
@ -6160,8 +6160,8 @@
"y": 6.031000137329102 "y": 6.031000137329102
}, },
{ {
"x": 1198.81005859375, "x": 1197.968994140625,
"y": 6.409999847412109 "y": 12.1899995803833
}, },
{ {
"x": 1199.4090576171875, "x": 1199.4090576171875,

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 47 KiB

After

Width:  |  Height:  |  Size: 47 KiB