diff --git a/src/extensions/dnatco/ntc-tube/representation.ts b/src/extensions/dnatco/ntc-tube/representation.ts
index cedbd31c5f626023f8f8cd477cb0ed9def9d2cbe..52023926a8a531f60a0e95b06e482e6a67c03cb2 100644
--- a/src/extensions/dnatco/ntc-tube/representation.ts
+++ b/src/extensions/dnatco/ntc-tube/representation.ts
@@ -316,7 +316,7 @@ function createNtCTubeMesh(ctx: VisualContext, unit: Unit, structure: Structure,
                 radiusTop: diameter / 2, radiusBottom: diameter / 2, topCap: true, bottomCap: true, radialSegments: segCount.radial,
             };
             mb.currentGroup = FirstBlockId;
-            addFixedCountDashedCylinder(mb, p_1, p1, 1, 2 * segCount.linear, cylinderProps);
+            addFixedCountDashedCylinder(mb, p_1, p1, 1, 2 * segCount.linear, false, cylinderProps);
         }
     }
 
diff --git a/src/mol-geo/geometry/cylinders/cylinders-builder.ts b/src/mol-geo/geometry/cylinders/cylinders-builder.ts
index 243ba71b087d97d6c4975c7430d3c75810c5584b..aa28124cf5da42846404e3ffcc63bf5a568d4b3c 100644
--- a/src/mol-geo/geometry/cylinders/cylinders-builder.ts
+++ b/src/mol-geo/geometry/cylinders/cylinders-builder.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2020-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Gianluca Tomasello <giagitom@gmail.com>
@@ -11,7 +11,7 @@ import { Vec3 } from '../../../mol-math/linear-algebra';
 
 export interface CylindersBuilder {
     add(startX: number, startY: number, startZ: number, endX: number, endY: number, endZ: number, radiusScale: number, topCap: boolean, bottomCap: boolean, group: number): void
-    addFixedCountDashes(start: Vec3, end: Vec3, segmentCount: number, radiusScale: number, topCap: boolean, bottomCap: boolean, group: number): void
+    addFixedCountDashes(start: Vec3, end: Vec3, segmentCount: number, radiusScale: number, topCap: boolean, bottomCap: boolean, stubCap: boolean, group: number): void
     addFixedLengthDashes(start: Vec3, end: Vec3, segmentLength: number, radiusScale: number, topCap: boolean, bottomCap: boolean, group: number): void
     getCylinders(): Cylinders
 }
@@ -42,7 +42,7 @@ export namespace CylindersBuilder {
             }
         };
 
-        const addFixedCountDashes = (start: Vec3, end: Vec3, segmentCount: number, radiusScale: number, topCap: boolean, bottomCap: boolean, group: number) => {
+        const addFixedCountDashes = (start: Vec3, end: Vec3, segmentCount: number, radiusScale: number, topCap: boolean, bottomCap: boolean, stubCap: boolean, group: number) => {
             const d = Vec3.distance(start, end);
             const isOdd = segmentCount % 2 !== 0;
             segmentCount++;
@@ -57,6 +57,7 @@ export namespace CylindersBuilder {
                 Vec3.add(tmpVecA, start, tmpDir);
                 if (isOdd && j === s - 1) {
                     Vec3.copy(tmpVecB, end);
+                    if (!stubCap) bottomCap = false;
                 } else {
                     Vec3.setMagnitude(tmpDir, tmpDir, d * (step * ((j + 1) * 2) + offset));
                     Vec3.add(tmpVecB, start, tmpDir);
@@ -70,7 +71,7 @@ export namespace CylindersBuilder {
             addFixedCountDashes,
             addFixedLengthDashes: (start: Vec3, end: Vec3, segmentLength: number, radiusScale: number, topCap: boolean, bottomCap: boolean, group: number) => {
                 const d = Vec3.distance(start, end);
-                addFixedCountDashes(start, end, d / segmentLength, radiusScale, topCap, bottomCap, group);
+                addFixedCountDashes(start, end, d / segmentLength, radiusScale, topCap, bottomCap, true, group);
             },
             getCylinders: () => {
                 const cylinderCount = groups.elementCount / 6;
diff --git a/src/mol-geo/geometry/lines/lines-builder.ts b/src/mol-geo/geometry/lines/lines-builder.ts
index c9cd2b7dbecda56c36c91ab94162e4313b99beb0..d8d512dd643d4410ee290dbf5de72dec3e32dd66 100644
--- a/src/mol-geo/geometry/lines/lines-builder.ts
+++ b/src/mol-geo/geometry/lines/lines-builder.ts
@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Gianluca Tomasello <giagitom@gmail.com>
  */
 
 import { ChunkedArray } from '../../../mol-data/util';
@@ -50,16 +51,23 @@ export namespace LinesBuilder {
 
         const addFixedCountDashes = (start: Vec3, end: Vec3, segmentCount: number, group: number) => {
             const d = Vec3.distance(start, end);
+            const isOdd = segmentCount % 2 !== 0;
+            segmentCount++;
             const s = Math.floor(segmentCount / 2);
             const step = 1 / segmentCount;
+            const offset = step / 2;
 
             Vec3.sub(tmpDir, end, start);
             for (let j = 0; j < s; ++j) {
-                const f = step * (j * 2 + 1);
+                const f = step * (j * 2 + 1) + offset;
                 Vec3.setMagnitude(tmpDir, tmpDir, d * f);
                 Vec3.add(tmpVecA, start, tmpDir);
-                Vec3.setMagnitude(tmpDir, tmpDir, d * step * ((j + 1) * 2));
-                Vec3.add(tmpVecB, start, tmpDir);
+                if (isOdd && j === s - 1) {
+                    Vec3.copy(tmpVecB, end);
+                } else {
+                    Vec3.setMagnitude(tmpDir, tmpDir, d * step * ((j + 1) * 2) + offset);
+                    Vec3.add(tmpVecB, start, tmpDir);
+                }
                 add(tmpVecA[0], tmpVecA[1], tmpVecA[2], tmpVecB[0], tmpVecB[1], tmpVecB[2], group);
             }
         };
@@ -111,4 +119,4 @@ function fillMappingAndIndices(n: number, mb: Float32Array, ib: Uint32Array) {
         ib[io] = o; ib[io + 1] = o + 1; ib[io + 2] = o + 2;
         ib[io + 3] = o + 1; ib[io + 4] = o + 3; ib[io + 5] = o + 2;
     }
-}
\ No newline at end of file
+}
diff --git a/src/mol-geo/geometry/mesh/builder/cylinder.ts b/src/mol-geo/geometry/mesh/builder/cylinder.ts
index d84dcecb613eded9a866b3d5a6c1b90a69c001ce..d432a13a405eff46f9fa3defb9361da152cd8905 100644
--- a/src/mol-geo/geometry/mesh/builder/cylinder.ts
+++ b/src/mol-geo/geometry/mesh/builder/cylinder.ts
@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Gianluca Tomasello <giagitom@gmail.com>
  */
 
 import { Vec3, Mat4 } from '../../../../mol-math/linear-algebra';
@@ -97,26 +98,31 @@ export function addDoubleCylinder(state: MeshBuilder.State, start: Vec3, end: Ve
     MeshBuilder.addPrimitive(state, tmpCylinderMat, cylinder);
 }
 
-export function addFixedCountDashedCylinder(state: MeshBuilder.State, start: Vec3, end: Vec3, lengthScale: number, segmentCount: number, props: BasicCylinderProps) {
+export function addFixedCountDashedCylinder(state: MeshBuilder.State, start: Vec3, end: Vec3, lengthScale: number, segmentCount: number, stubCap: boolean, props: BasicCylinderProps) {
+    const d = Vec3.distance(start, end) * lengthScale;
+    const isOdd = segmentCount % 2 !== 0;
+    segmentCount++;
     const s = Math.floor(segmentCount / 2);
     const step = 1 / segmentCount;
+    const offset = step / 2;
 
-    // automatically adjust length so links/bonds that are rendered as two half cylinders
-    // have evenly spaced dashed cylinders
-    if (lengthScale < 1) {
-        const bias = lengthScale / 2 / segmentCount;
-        lengthScale += segmentCount % 2 === 1 ? bias : -bias;
-    }
-
-    const d = Vec3.distance(start, end) * lengthScale;
-    const cylinder = getCylinder(props);
+    let cylinder = getCylinder(props);
     Vec3.sub(tmpCylinderDir, end, start);
 
     for (let j = 0; j < s; ++j) {
-        const f = step * (j * 2 + 1);
+        const f = step * (j * 2 + 1) + offset;
+        let len = d * step;
         Vec3.setMagnitude(tmpCylinderDir, tmpCylinderDir, d * f);
         Vec3.add(tmpCylinderStart, start, tmpCylinderDir);
-        setCylinderMat(tmpCylinderMat, tmpCylinderStart, tmpCylinderDir, d * step, false);
+
+        if (isOdd && j === s - 1) {
+            if (!stubCap && props.topCap) {
+                props.topCap = false;
+                cylinder = getCylinder(props);
+            }
+            len /= 2;
+        }
+        setCylinderMat(tmpCylinderMat, tmpCylinderStart, tmpCylinderDir, len, false);
         MeshBuilder.addPrimitive(state, tmpCylinderMat, cylinder);
     }
-}
\ No newline at end of file
+}
diff --git a/src/mol-model-props/computed/representations/shared.ts b/src/mol-model-props/computed/representations/shared.ts
index 61d70bf0745baf00cd9de2ae558a3e19116e54c1..c49effa27d37aa1bec1706710425791d32367036 100644
--- a/src/mol-model-props/computed/representations/shared.ts
+++ b/src/mol-model-props/computed/representations/shared.ts
@@ -1,14 +1,15 @@
 /**
- * Copyright (c) 2022 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2022-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Gianluca Tomasello <giagitom@gmail.com>
  */
 
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
 
 export const InteractionsSharedParams = {
     sizeFactor: PD.Numeric(0.3, { min: 0, max: 10, step: 0.01 }),
-    dashCount: PD.Numeric(6, { min: 2, max: 10, step: 2 }),
+    dashCount: PD.Numeric(6, { min: 1, max: 10, step: 1 }),
     dashScale: PD.Numeric(0.4, { min: 0, max: 2, step: 0.1 }),
     includeParent: PD.Boolean(false),
     parentDisplay: PD.Select('stub', PD.arrayToOptions(['stub', 'full', 'between'] as const), { description: 'Only has an effect when "includeParent" is enabled. "Stub" shows just the child side of interactions to the parent. "Full" shows both sides of interactions to the parent. "Between" shows only interactions to the parent.' }),
diff --git a/src/mol-repr/structure/visual/polymer-gap-cylinder.ts b/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
index 5dcfbe56647cf0ee0bedbc86093457944182be68..01f00a47820020b98345458bbd2ac275aa43decc 100644
--- a/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
+++ b/src/mol-repr/structure/visual/polymer-gap-cylinder.ts
@@ -1,7 +1,8 @@
 /**
- * Copyright (c) 2018-2019 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ * @author Gianluca Tomasello <giagitom@gmail.com>
  */
 
 import { ParamDefinition as PD } from '../../../mol-util/param-definition';
@@ -68,11 +69,11 @@ function createPolymerGapCylinderMesh(ctx: VisualContext, unit: Unit, structure:
 
             cylinderProps.radiusTop = cylinderProps.radiusBottom = theme.size.size(centerA) * sizeFactor;
             builderState.currentGroup = i;
-            addFixedCountDashedCylinder(builderState, pA, pB, 0.5, segmentCount, cylinderProps);
+            addFixedCountDashedCylinder(builderState, pA, pB, 0.5, segmentCount, false, cylinderProps);
 
             cylinderProps.radiusTop = cylinderProps.radiusBottom = theme.size.size(centerB) * sizeFactor;
             builderState.currentGroup = i + 1;
-            addFixedCountDashedCylinder(builderState, pB, pA, 0.5, segmentCount, cylinderProps);
+            addFixedCountDashedCylinder(builderState, pB, pA, 0.5, segmentCount, false, cylinderProps);
         }
 
         i += 2;
@@ -106,4 +107,4 @@ export function PolymerGapVisual(materialId: number): UnitsVisual<PolymerGapPara
             );
         }
     }, materialId);
-}
\ No newline at end of file
+}
diff --git a/src/mol-repr/structure/visual/util/link.ts b/src/mol-repr/structure/visual/util/link.ts
index 5193af600b5f75cf5c4e4c5b5e43646857211a03..d7560ed963f10834f907f977ee30ecbadbc9f5eb 100644
--- a/src/mol-repr/structure/visual/util/link.ts
+++ b/src/mol-repr/structure/visual/util/link.ts
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2018-2021 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ * Copyright (c) 2018-2023 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
  * @author Alexander Rose <alexander.rose@weirdbyte.de>
  * @author Zhenyu Zhang <jump2cn@gmail.com>
@@ -27,7 +27,7 @@ export const LinkCylinderParams = {
     aromaticScale: PD.Numeric(0.3, { min: 0, max: 1, step: 0.01 }),
     aromaticSpacing: PD.Numeric(1.5, { min: 0, max: 3, step: 0.01 }),
     aromaticDashCount: PD.Numeric(2, { min: 1, max: 6, step: 1 }),
-    dashCount: PD.Numeric(4, { min: 0, max: 10, step: 2 }),
+    dashCount: PD.Numeric(4, { min: 0, max: 10, step: 1 }),
     dashScale: PD.Numeric(0.8, { min: 0, max: 2, step: 0.1 }),
     dashCap: PD.Boolean(true),
     stubCap: PD.Boolean(true),
@@ -39,8 +39,8 @@ export type LinkCylinderProps = typeof DefaultLinkCylinderProps
 export const LinkLineParams = {
     linkScale: PD.Numeric(0.5, { min: 0, max: 1, step: 0.1 }),
     linkSpacing: PD.Numeric(0.1, { min: 0, max: 2, step: 0.01 }),
-    aromaticDashCount: PD.Numeric(2, { min: 2, max: 6, step: 2 }),
-    dashCount: PD.Numeric(4, { min: 0, max: 10, step: 2 }),
+    aromaticDashCount: PD.Numeric(2, { min: 1, max: 6, step: 1 }),
+    dashCount: PD.Numeric(4, { min: 0, max: 10, step: 1 }),
 };
 export const DefaultLinkLineProps = PD.getDefaultValues(LinkLineParams);
 export type LinkLineProps = typeof DefaultLinkLineProps
@@ -134,8 +134,6 @@ export function createLinkCylinderMesh(ctx: VisualContext, linkBuilder: LinkBuil
         bottomCap: linkCap
     };
 
-    const segmentCount = dashCount + 1;
-
     for (let edgeIndex = 0, _eI = linkCount; edgeIndex < _eI; ++edgeIndex) {
         if (ignore && ignore(edgeIndex)) continue;
 
@@ -154,8 +152,6 @@ export function createLinkCylinderMesh(ctx: VisualContext, linkBuilder: LinkBuil
         const [topCap, bottomCap] = dirFlag ? [linkStub, linkCap] : [linkCap, linkStub];
         builderState.currentGroup = edgeIndex;
 
-        const aromaticSegmentCount = aromaticDashCount + 1;
-
         if (linkStyle === LinkStyle.Solid) {
             cylinderProps.radiusTop = cylinderProps.radiusBottom = linkRadius;
             cylinderProps.topCap = topCap;
@@ -165,12 +161,7 @@ export function createLinkCylinderMesh(ctx: VisualContext, linkBuilder: LinkBuil
         } else if (linkStyle === LinkStyle.Dashed) {
             cylinderProps.radiusTop = cylinderProps.radiusBottom = linkRadius * dashScale;
             cylinderProps.topCap = cylinderProps.bottomCap = dashCap;
-
-            if (segmentCount > 1) {
-                addFixedCountDashedCylinder(builderState, va, vb, 0.5, segmentCount, cylinderProps);
-            } else {
-                addCylinder(builderState, va, vb, 0.5, cylinderProps);
-            }
+            addFixedCountDashedCylinder(builderState, va, vb, 0.5, dashCount, linkStub, cylinderProps);
         } else if (linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple || linkStyle === LinkStyle.Aromatic || linkStyle === LinkStyle.MirroredAromatic) {
             const order = (linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble) ? 2 :
                 (linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple) ? 3 : 1.5;
@@ -197,13 +188,13 @@ export function createLinkCylinderMesh(ctx: VisualContext, linkBuilder: LinkBuil
                 v3setMagnitude(vShift, vShift, aromaticOffset);
                 v3sub(va, va, vShift);
                 v3sub(vb, vb, vShift);
-                addFixedCountDashedCylinder(builderState, va, vb, 0.5, aromaticSegmentCount, cylinderProps);
+                addFixedCountDashedCylinder(builderState, va, vb, 0.5, aromaticDashCount, linkStub, cylinderProps);
 
                 if (linkStyle === LinkStyle.MirroredAromatic) {
                     v3setMagnitude(vShift, vShift, aromaticOffset * 2);
                     v3add(va, va, vShift);
                     v3add(vb, vb, vShift);
-                    addFixedCountDashedCylinder(builderState, va, vb, 0.5, aromaticSegmentCount, cylinderProps);
+                    addFixedCountDashedCylinder(builderState, va, vb, 0.5, aromaticDashCount, linkStub, cylinderProps);
                 }
             } else if (linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.OffsetTriple) {
                 const multipleOffset = linkRadius + multiRadius + linkScale * linkRadius * linkSpacing;
@@ -285,9 +276,6 @@ export function createLinkCylinderImpostors(ctx: VisualContext, linkBuilder: Lin
     const center = Vec3();
     let count = 0;
 
-    // automatically adjust length for evenly spaced dashed cylinders
-    const segmentCount = dashCount % 2 === 1 ? dashCount : dashCount + 1;
-
     for (let edgeIndex = 0, _eI = linkCount; edgeIndex < _eI; ++edgeIndex) {
         if (ignore && ignore(edgeIndex)) continue;
 
@@ -306,11 +294,7 @@ export function createLinkCylinderImpostors(ctx: VisualContext, linkBuilder: Lin
             builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], 1, linkCap, linkStub, edgeIndex);
         } else if (linkStyle === LinkStyle.Dashed) {
             v3scale(vm, v3add(vm, va, vb), 0.5);
-            if (segmentCount > 1) {
-                builder.addFixedCountDashes(va, vm, segmentCount, dashScale, dashCap, dashCap, edgeIndex);
-            } else {
-                builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], dashScale, dashCap, dashCap, edgeIndex);
-            }
+            builder.addFixedCountDashes(va, vm, dashCount, dashScale, dashCap, dashCap, linkStub, edgeIndex);
         } else if (linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple || linkStyle === LinkStyle.Aromatic || linkStyle === LinkStyle.MirroredAromatic) {
             const order = (linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble) ? 2 :
                 (linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple) ? 3 : 1.5;
@@ -325,19 +309,16 @@ export function createLinkCylinderImpostors(ctx: VisualContext, linkBuilder: Lin
 
                 const aromaticOffset = linkRadius + aromaticScale * linkRadius + aromaticScale * linkRadius * aromaticSpacing;
 
-                v3setMagnitude(tmpV12, v3sub(tmpV12, vm, va), linkRadius * 0.5);
-                v3add(va, va, tmpV12);
-
                 v3setMagnitude(vShift, vShift, aromaticOffset);
                 v3sub(va, va, vShift);
                 v3sub(vm, vm, vShift);
-                builder.addFixedCountDashes(va, vm, aromaticDashCount, aromaticScale, dashCap, dashCap, edgeIndex);
+                builder.addFixedCountDashes(va, vm, aromaticDashCount, aromaticScale, dashCap, dashCap, linkStub, edgeIndex);
 
                 if (linkStyle === LinkStyle.MirroredAromatic) {
                     v3setMagnitude(vShift, vShift, aromaticOffset * 2);
                     v3add(va, va, vShift);
                     v3add(vm, vm, vShift);
-                    builder.addFixedCountDashes(va, vm, aromaticDashCount, aromaticScale, dashCap, dashCap, edgeIndex);
+                    builder.addFixedCountDashes(va, vm, aromaticDashCount, aromaticScale, dashCap, dashCap, linkStub, edgeIndex);
                 }
             } else if (linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.OffsetTriple) {
                 const multipleOffset = linkRadius + multiScale * linkRadius + linkScale * linkRadius * linkSpacing;
@@ -401,12 +382,6 @@ export function createLinkLines(ctx: VisualContext, linkBuilder: LinkBuilderProp
     const center = Vec3();
     let count = 0;
 
-    // automatically adjust length for evenly spaced dashed lines
-    const segmentCount = dashCount % 2 === 1 ? dashCount : dashCount + 1;
-    const lengthScale = 0.5 - (0.5 / 2 / segmentCount);
-
-    const aromaticSegmentCount = aromaticDashCount + 1;
-    const aromaticLengthScale = 0.5 - (0.5 / 2 / aromaticSegmentCount);
     const aromaticOffsetFactor = 4.5;
     const multipleOffsetFactor = 3;
 
@@ -425,14 +400,8 @@ export function createLinkLines(ctx: VisualContext, linkBuilder: LinkBuilderProp
             v3scale(vm, v3add(vm, va, vb), 0.5);
             builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], edgeIndex);
         } else if (linkStyle === LinkStyle.Dashed) {
-            if (segmentCount > 1) {
-                v3scale(tmpV12, v3sub(tmpV12, vb, va), lengthScale);
-                v3sub(vb, vb, tmpV12);
-                builder.addFixedCountDashes(va, vb, segmentCount, edgeIndex);
-            } else {
-                v3scale(vm, v3add(vm, va, vb), 0.5);
-                builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], edgeIndex);
-            }
+            v3scale(vm, v3add(vm, va, vb), 0.5);
+            builder.addFixedCountDashes(va, vm, dashCount, edgeIndex);
         } else if (linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple || linkStyle === LinkStyle.Aromatic || linkStyle === LinkStyle.MirroredAromatic) {
             const order = linkStyle === LinkStyle.Double || linkStyle === LinkStyle.OffsetDouble ? 2 :
                 linkStyle === LinkStyle.Triple || linkStyle === LinkStyle.OffsetTriple ? 3 : 1.5;
@@ -445,26 +414,23 @@ export function createLinkLines(ctx: VisualContext, linkBuilder: LinkBuilderProp
             if (linkStyle === LinkStyle.Aromatic || linkStyle === LinkStyle.MirroredAromatic) {
                 builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], edgeIndex);
 
-                v3scale(tmpV12, v3sub(tmpV12, vb, va), aromaticLengthScale);
-                v3sub(vb, vb, tmpV12);
-
                 v3setMagnitude(vShift, vShift, absOffset * aromaticOffsetFactor);
                 v3sub(va, va, vShift);
-                v3sub(vb, vb, vShift);
-                builder.addFixedCountDashes(va, vb, aromaticSegmentCount, edgeIndex);
+                v3sub(vm, vm, vShift);
+                builder.addFixedCountDashes(va, vm, aromaticDashCount, edgeIndex);
 
                 if (linkStyle === LinkStyle.MirroredAromatic) {
                     v3setMagnitude(vShift, vShift, absOffset * aromaticOffsetFactor * 2);
                     v3add(va, va, vShift);
-                    v3add(vb, vb, vShift);
-                    builder.addFixedCountDashes(va, vb, aromaticSegmentCount, edgeIndex);
+                    v3add(vm, vm, vShift);
+                    builder.addFixedCountDashes(va, vm, aromaticDashCount, edgeIndex);
                 }
             } else if (linkStyle === LinkStyle.OffsetDouble || linkStyle === LinkStyle.OffsetTriple) {
                 v3setMagnitude(vShift, vShift, absOffset * multipleOffsetFactor);
 
                 builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], edgeIndex);
 
-                v3scale(tmpV12, v3sub(tmpV12, va, vb), linkSpacing * linkScale);
+                v3scale(tmpV12, v3sub(tmpV12, va, vm), linkSpacing * linkScale);
                 v3sub(va, va, tmpV12);
 
                 if (order === 3) builder.add(va[0] + vShift[0], va[1] + vShift[1], va[2] + vShift[2], vm[0] + vShift[0], vm[1] + vShift[1], vm[2] + vShift[2], edgeIndex);
@@ -477,12 +443,12 @@ export function createLinkLines(ctx: VisualContext, linkBuilder: LinkBuilderProp
                 builder.add(va[0] - vShift[0], va[1] - vShift[1], va[2] - vShift[2], vm[0] - vShift[0], vm[1] - vShift[1], vm[2] - vShift[2], edgeIndex);
             }
         } else if (linkStyle === LinkStyle.Disk) {
-            v3scale(tmpV12, v3sub(tmpV12, vb, va), 0.475);
+            v3scale(tmpV12, v3sub(tmpV12, vm, va), 0.475);
             v3add(va, va, tmpV12);
-            v3sub(vb, vb, tmpV12);
+            v3sub(vm, vm, tmpV12);
 
             // TODO what to do here? Line as disk doesn't work well.
-            builder.add(va[0], va[1], va[2], vb[0], vb[1], vb[2], edgeIndex);
+            builder.add(va[0], va[1], va[2], vm[0], vm[1], vm[2], edgeIndex);
         }
     }