From a68d666d27176690ad95e6ed9a681f8a453d8803 Mon Sep 17 00:00:00 2001 From: Moonlit Productions Date: Mon, 27 Oct 2025 10:31:29 -0400 Subject: [PATCH] Added robot presets and draw robot and basic grid functions --- script.js | 118 +++++++++++++++++++++++++++++++++++++++++++++++++++-- styles.css | 6 +++ 2 files changed, 121 insertions(+), 3 deletions(-) diff --git a/script.js b/script.js index f3d830e..e0be27e 100644 --- a/script.js +++ b/script.js @@ -29,8 +29,8 @@ class SwerveModule { // speed and angle of this module to achieve it // Calculate rotation contribution (perpendicular to position vector) - const rotX = -this.position.y * omega; - const rotY = this.position.x * omega; + const rotX = -this.position.y * turnSpeed; + const rotY = this.position.x * turnSpeed; // Combine translation and rotation this.velocity.x = velocityX + rotX; @@ -68,6 +68,72 @@ class SwerveDrive { } } +// Preset robot generators +const PresetConfigs = { + twoWheel: (size) => [ + { x: 0, y: size / 2, name: "Left" }, + { x: 0, y: -size / 2, name: "Right" } + ], + + threeWheel: (size) => { + const radius = size / 2; + return [ + { x: radius * Math.cos(Math.PI / 2), y: radius * Math.sin(Math.PI / 2), name: "Front" }, + { x: radius * Math.cos(Math.PI / 2 + 2 * Math.PI / 3), y: radius * Math.sin(Math.PI / 2 + 2 * Math.PI / 3), name: "Back Left" }, + { x: radius * Math.cos(Math.PI / 2 + 4 * Math.PI / 3), y: radius * Math.sin(Math.PI / 2 + 4 * Math.PI / 3), name: "Back Right" } + ]; + }, + + fourWheelSquare: (size) => { + const half = size / 2; + return [ + { x: half, y: half, name: "FL" }, + { x: half, y: -half, name: "FR" }, + { x: -half, y: half, name: "BL" }, + { x: -half, y: -half, name: "BR" } + ]; + }, + + fourWheelRectangle: (size) => { + const width = size * 0.7; + const length = size; + return [ + { x: length / 2, y: width / 2, name: "FL" }, + { x: length / 2, y: -width / 2, name: "FR" }, + { x: -length / 2, y: width / 2, name: "BL" }, + { x: -length / 2, y: -width / 2, name: "BR" } + ]; + }, + + sixWheel: (size) => { + const radius = size / 2; + const modules = []; + for (let i = 0; i < 6; i++) { + const angle = (Math.PI / 2) + (i * Math.PI / 3); + modules.push({ + x: radius * Math.cos(angle), + y: radius * Math.sin(angle), + name: `Module ${i + 1}` + }); + } + return modules; + }, + + eightWheel: (size) => { + const radius = size / 2; + const modules = []; + for (let i = 0; i < 8; i++) { + const angle = (Math.PI / 2) + (i * Math.PI / 4); + modules.push({ + x: radius * Math.cos(angle), + y: radius * Math.sin(angle), + name: `Module ${i + 1}` + }); + } + return modules; + } +}; + // Get all control elements const vxSlider = document.getElementById('vx-slider'); const vySlider = document.getElementById('vy-slider'); @@ -109,4 +175,50 @@ omegaSlider.addEventListener('input', (e) => { maxSpeedSlider.addEventListener('input', (e) => { maxSpeedOutput.textContent = parseFloat(e.target.value).toFixed(1); -}); \ No newline at end of file +}); + +// Get the canvas and context as constants +const canvas = document.getElementById('swerve-canvas'); +const ctx = canvas.getContext('2d'); + +// Get CSS variables for use in canvas +const rootStyles = getComputedStyle(document.documentElement); + +function drawGrid(ctx, sideLength, gridSquareSize) { + ctx.strokeStyle = rootStyles.getPropertyValue('--grid-color'); + ctx.lineWidth = 1; + + for (let i = -sideLength / 2; i <= sideLength / 2; i += gridSquareSize) { + ctx.beginPath(); + ctx.moveTo(i, -sideLength / 2); + ctx.lineTo(i, sideLength / 2); + ctx.stroke(); + + ctx.beginPath(); + ctx.moveTo(-sideLength / 2, i); + ctx.lineTo(sideLength / 2, i); + ctx.stroke(); + } +} + +function drawRobot(ctx, robot) { + ctx.strokeStyle = rootStyles.getPropertyValue('--robot-frame-color') + ctx.fillStyle = rootStyles.getPropertyValue('--robot-fill-color'); + ctx.lineWidth = 4; + + const modules = robot.modules.sort((a, b) => Math.atan2(a.position.y, a.position.x) - Math.atan2(b.position.y, b.position.x)); + console.log(modules); + + ctx.beginPath(); + ctx.moveTo(modules[0].position.x, modules[0].position.y); + for (let i = 1; i < modules.length; i++) { + ctx.lineTo(modules[i].position.x, modules[i].position.y); + } + ctx.closePath(); + ctx.fill(); + ctx.stroke(); +} + +ctx.translate(canvas.width / 2, canvas.height / 2); +drawGrid(ctx, 600, 50); +drawRobot(ctx, new SwerveDrive(PresetConfigs.eightWheel(200))); \ No newline at end of file diff --git a/styles.css b/styles.css index a902b4f..b26b162 100644 --- a/styles.css +++ b/styles.css @@ -22,6 +22,12 @@ --border-radius-sm: 4px; --shadow: 0 4px 6px rgba(0, 0, 0, 0.3); + + --grid-color: #e4e4e733; + --robot-frame-color: #1e81bf; + --robot-fill-color: #5f9ec4; + --swerve-module-color: #7bb6db; + --swerve-arrow-color: #c73c3c; } body {