Skip to content

Commit

Permalink
Merge pull request #44 from igloo-4002/mutaz/two-way-roads
Browse files Browse the repository at this point in the history
Arrow markings on roads to display direction
  • Loading branch information
MutazAshhab authored Sep 11, 2023
2 parents d6e3270 + 00945fd commit cbb0b14
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
9 changes: 8 additions & 1 deletion .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@ module.exports = {
{ allowConstantExport: true },
],
curly: 'error',
'@typescript-eslint/no-unused-vars': 'warn',
'@typescript-eslint/no-unused-vars': [
'warn',
{
argsIgnorePattern: '^_',
varsIgnorePattern: '^_',
caughtErrorsIgnorePattern: '^_',
},
],
'react-hooks/exhaustive-deps': 'off',
},
};
1 change: 0 additions & 1 deletion src/components/Canvas/Intersection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ export function Intersection({ node }: IntersectionProps) {
fill="grey"
stroke={isSelected ? highlightColor : 'transparent'}
strokeWidth={4}
zIndex={1}
draggable
onDragEnd={handleDragMove}
/>
Expand Down
15 changes: 14 additions & 1 deletion src/components/Canvas/Layers/RoadsLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,24 @@ import { Road } from '../Road';
export function RoadsLayer() {
const network = useNetworkStore();
const edges = Object.values(network.edges);
const renderedEdges = new Set(); // Keep track of bidirectional roads that are already rendered

return (
<Layer>
{edges.map((edge, index) => {
return <Road edge={edge} key={index} />;
const isRendered = renderedEdges.has(edge.id);

if (isRendered) {
return null; // Skip rendering if this edge has already been rendered
}

const bidirectionalEdge = network.edges[`${edge.to}_${edge.from}`];

if (bidirectionalEdge) {
renderedEdges.add(bidirectionalEdge.id); // Mark the edge going the other way as rendered.
}

return <Road edge={edge} reverseEdge={bidirectionalEdge} key={index} />;
})}
</Layer>
);
Expand Down
51 changes: 44 additions & 7 deletions src/components/Canvas/Road.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import { useSelector } from '~/zustand/useSelected';

interface RoadProps {
edge: Edge;
reverseEdge?: Edge;
}

export const laneWidth = 25;

export function Road({ edge }: RoadProps) {
export function Road({ edge, reverseEdge }: RoadProps) {
const network = useNetworkStore();
const selector = useSelector();

const _isBidirectional = !!reverseEdge;

const isSelected = selector.selected === edge.id;

const from = network.nodes[edge.from];
Expand All @@ -35,9 +38,19 @@ export function Road({ edge }: RoadProps) {
points: [0, 0, to.x - from.x, to.y - from.y],
pointerLength: 0,
pointerWidth: 0,
zIndex: -1,
};

const angleRad = Math.atan2(to.y - from.y, to.x - from.x);
const angleDeg = (angleRad * 180) / Math.PI;

// Calculate the offset in both x and y directions
const dx = laneWidth * Math.sin(angleRad);
const dy = laneWidth * Math.cos(angleRad);

// Calculate the mid-point of the lane
const midX = (from.x + to.x) / 2;
const midY = (from.y + to.y) / 2;

return (
<Group onClick={handleRoadClick}>
{/* Highlight for selected road */}
Expand All @@ -63,19 +76,43 @@ export function Road({ edge }: RoadProps) {

{/* Lanes */}
{Array.from({ length: edge.numLanes - 1 }).map((_, index) => {
const yOffset =
(index + 0.5) * laneWidth - (edge.numLanes - 1) * (laneWidth / 2);
const offset = index + 0.5 - (edge.numLanes - 1) / 2;

return (
<Arrow
key={`centerline-${edge.id}-${index}`}
x={from.x}
y={from.y + yOffset}
x={from.x + offset * dx}
y={from.y - offset * dy}
points={[0, 0, to.x - from.x, to.y - from.y]}
dash={[10, 10]}
fill="transparent"
stroke={centerlineColor}
strokeWidth={2}
{...commonProps}
/>
);
})}

{/* Arrow for traffic direction */}
{Array.from({ length: edge.numLanes }).map((_, index) => {
const yOffset =
index * laneWidth - (edge.numLanes - 1) * (laneWidth / 2);

// Calculating rotated offset
const offsetX = midX + yOffset * Math.sin(angleRad);
const offsetY = midY - yOffset * Math.cos(angleRad);

return (
<Arrow
key={`arrow-${edge.id}-${index}`}
x={offsetX}
y={offsetY}
points={[0, 0, 20 * Math.cos(angleRad), 20 * Math.sin(angleRad)]}
pointerLength={10}
pointerWidth={10}
fill="white"
stroke="white"
strokeWidth={2}
angle={angleDeg}
/>
);
})}
Expand Down
1 change: 0 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,

Expand Down

0 comments on commit cbb0b14

Please sign in to comment.