Compare commits
7 Commits
323a767abc
...
0e9500196f
| Author | SHA1 | Date | |
|---|---|---|---|
| 0e9500196f | |||
| 77cb74ad10 | |||
| 4e5b4fb249 | |||
| 0753ef40d5 | |||
| 09ff88289b | |||
| 388f7633e5 | |||
| 0db7cab23b |
@ -19,6 +19,16 @@ npm run build
|
|||||||
npm run preview
|
npm run preview
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Scripts
|
||||||
|
|
||||||
|
The `script/` folder contains utility scripts for development:
|
||||||
|
|
||||||
|
- **screenshot**: Captures a screenshot of the running dev server (localhost:5173) using Chrome headless mode
|
||||||
|
- Outputs to `screenshot.png` in the project root
|
||||||
|
- Requires Chrome/Chromium to be installed
|
||||||
|
- Dev server must be running before executing
|
||||||
|
- Usage: `./script/screenshot`
|
||||||
|
|
||||||
## Architecture
|
## Architecture
|
||||||
|
|
||||||
### Application Structure
|
### Application Structure
|
||||||
|
|||||||
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
An interactive geometric visualization tool that demonstrates rectangle area calculations and their relationship to a line segment.
|
An interactive geometric visualization tool that demonstrates rectangle area calculations and their relationship to a line segment.
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## Use Case
|
## Use Case
|
||||||
|
|
||||||
This tool provides a visual and interactive way to understand how moving a point affects the areas of rectangles formed with fixed anchor points. It's useful for:
|
This tool provides a visual and interactive way to understand how moving a point affects the areas of rectangles formed with fixed anchor points. It's useful for:
|
||||||
@ -17,8 +19,8 @@ The visualization displays:
|
|||||||
- **Point C** at (6, 7) - top-right anchor point
|
- **Point C** at (6, 7) - top-right anchor point
|
||||||
- **Point B** - movable point that follows your mouse cursor
|
- **Point B** - movable point that follows your mouse cursor
|
||||||
- **Line segment AC** - connecting the two fixed points
|
- **Line segment AC** - connecting the two fixed points
|
||||||
- **Blue rectangle** - formed by points B and C
|
- **Blue rectangle** - formed by point B and (cx, ay) = (6, 1)
|
||||||
- **Red rectangle** - formed by points B and A
|
- **Red rectangle** - formed by point B and (ax, cy) = (1, 7)
|
||||||
|
|
||||||
As you move your mouse over the canvas, point B follows the cursor, and the application:
|
As you move your mouse over the canvas, point B follows the cursor, and the application:
|
||||||
1. Calculates the width and height of both rectangles in real-time
|
1. Calculates the width and height of both rectangles in real-time
|
||||||
@ -56,7 +58,7 @@ npm run preview
|
|||||||
|
|
||||||
## Interface
|
## Interface
|
||||||
|
|
||||||
The canvas displays an 8×8 grid where each cell is 40 pixels. Move your mouse over the grid to control point B and watch the rectangle areas update in real-time below the visualization.
|
The canvas displays an 8x8 grid where each cell is 40 pixels. Move your mouse over the grid to control point B and watch the rectangle areas update in real-time below the visualization.
|
||||||
|
|
||||||
The calculation cards show:
|
The calculation cards show:
|
||||||
- Current position of point B
|
- Current position of point B
|
||||||
|
|||||||
BIN
line-segment-intersection/screenshot.png
Normal file
BIN
line-segment-intersection/screenshot.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 38 KiB |
7
line-segment-intersection/script/screenshot
Executable file
7
line-segment-intersection/script/screenshot
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
google-chrome --headless --disable-gpu \
|
||||||
|
--screenshot=$(pwd)/screenshot.png --window-size=1280,900 \
|
||||||
|
http://localhost:5173 2>/dev/null
|
||||||
@ -8,6 +8,7 @@
|
|||||||
const HEIGHT = 320;
|
const HEIGHT = 320;
|
||||||
|
|
||||||
let userPoint = { x: 5, y: 2 };
|
let userPoint = { x: 5, y: 2 };
|
||||||
|
let trackHover = true;
|
||||||
|
|
||||||
// Rectangle coordinates
|
// Rectangle coordinates
|
||||||
const blueRect = { x1: 6, y1: 1 }; // Blue rectangle corner
|
const blueRect = { x1: 6, y1: 1 }; // Blue rectangle corner
|
||||||
@ -50,16 +51,33 @@
|
|||||||
const width = Math.abs(corner2.x - corner1.x);
|
const width = Math.abs(corner2.x - corner1.x);
|
||||||
const height = Math.abs(corner2.y - corner1.y);
|
const height = Math.abs(corner2.y - corner1.y);
|
||||||
|
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.roundRect(x, y, width, height, 1);
|
||||||
ctx.fillStyle = color;
|
ctx.fillStyle = color;
|
||||||
ctx.fillRect(x, y, width, height);
|
ctx.fill();
|
||||||
|
|
||||||
|
// Add border
|
||||||
|
ctx.strokeStyle = color.replace('0.3', '0.8'); // Make border more opaque
|
||||||
|
ctx.lineWidth = 2;
|
||||||
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleMouseMove(event) {
|
function handleMouseMove(event) {
|
||||||
|
if (!trackHover) return;
|
||||||
|
|
||||||
const rect = canvas.getBoundingClientRect();
|
const rect = canvas.getBoundingClientRect();
|
||||||
const mouseX = event.clientX - rect.left;
|
const mouseX = event.clientX - rect.left;
|
||||||
const mouseY = event.clientY - rect.top;
|
const mouseY = event.clientY - rect.top;
|
||||||
|
|
||||||
userPoint = toCartesianCoords(mouseX, mouseY);
|
// Add half grid unit offset for snapping to closest grid intersection
|
||||||
|
userPoint = {
|
||||||
|
x: Math.floor((mouseX + GRID_SIZE / 2) / GRID_SIZE),
|
||||||
|
y: Math.floor((HEIGHT - mouseY + GRID_SIZE / 2) / GRID_SIZE)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCanvasClick() {
|
||||||
|
trackHover = !trackHover;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toCanvasCoords(x, y) {
|
function toCanvasCoords(x, y) {
|
||||||
@ -194,27 +212,27 @@
|
|||||||
<main>
|
<main>
|
||||||
<h1>Line Segment Intersection</h1>
|
<h1>Line Segment Intersection</h1>
|
||||||
<div class="canvas-container">
|
<div class="canvas-container">
|
||||||
<canvas bind:this={canvas} width={WIDTH} height={HEIGHT} on:mousemove={handleMouseMove}></canvas>
|
<canvas bind:this={canvas} width={WIDTH} height={HEIGHT} on:mousemove={handleMouseMove} on:click={handleCanvasClick}></canvas>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="calculations">
|
<div class="calculations">
|
||||||
<h2>Rectangle Areas</h2>
|
<h2>Rectangle Areas</h2>
|
||||||
<p class="point-c">Point B: ({userPoint.x.toFixed(2)}, {userPoint.y.toFixed(2)})</p>
|
<p class="point-c">Point B: ({userPoint.x}, {userPoint.y})</p>
|
||||||
|
|
||||||
<div class="rect-calc blue" class:largest={blueArea > redArea}>
|
<div class="rect-calc blue" class:largest={blueArea > redArea}>
|
||||||
<h3>Blue Rectangle</h3>
|
<h3>Blue Rectangle</h3>
|
||||||
<p>Corner: ({blueRect.x1}, {blueRect.y1})</p>
|
<p>Corner: ({blueRect.x1}, {blueRect.y1})</p>
|
||||||
<p>Width = |{blueRect.x1} - {userPoint.x.toFixed(2)}| = {blueWidth.toFixed(2)}</p>
|
<p>Width = |{blueRect.x1} - {userPoint.x}| = {blueWidth}</p>
|
||||||
<p>Height = |{blueRect.y1} - {userPoint.y.toFixed(2)}| = {blueHeight.toFixed(2)}</p>
|
<p>Height = |{blueRect.y1} - {userPoint.y}| = {blueHeight}</p>
|
||||||
<p class="area">Area = {blueWidth.toFixed(2)} × {blueHeight.toFixed(2)} = <strong>{blueArea.toFixed(2)}</strong></p>
|
<p class="area">Area = {blueWidth} x {blueHeight} = <strong>{blueArea}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="rect-calc red" class:largest={redArea > blueArea}>
|
<div class="rect-calc red" class:largest={redArea > blueArea}>
|
||||||
<h3>Red Rectangle</h3>
|
<h3>Red Rectangle</h3>
|
||||||
<p>Corner: ({redRect.x1}, {redRect.y1})</p>
|
<p>Corner: ({redRect.x1}, {redRect.y1})</p>
|
||||||
<p>Width = |{redRect.x1} - {userPoint.x.toFixed(2)}| = {redWidth.toFixed(2)}</p>
|
<p>Width = |{redRect.x1} - {userPoint.x}| = {redWidth}</p>
|
||||||
<p>Height = |{redRect.y1} - {userPoint.y.toFixed(2)}| = {redHeight.toFixed(2)}</p>
|
<p>Height = |{redRect.y1} - {userPoint.y}| = {redHeight}</p>
|
||||||
<p class="area">Area = {redWidth.toFixed(2)} × {redHeight.toFixed(2)} = <strong>{redArea.toFixed(2)}</strong></p>
|
<p class="area">Area = {redWidth} x {redHeight} = <strong>{redArea}</strong></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
@ -240,6 +258,7 @@
|
|||||||
|
|
||||||
canvas {
|
canvas {
|
||||||
display: block;
|
display: block;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.calculations {
|
.calculations {
|
||||||
|
|||||||
@ -1,10 +0,0 @@
|
|||||||
<script>
|
|
||||||
let count = $state(0)
|
|
||||||
const increment = () => {
|
|
||||||
count += 1
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<button onclick={increment}>
|
|
||||||
count is {count}
|
|
||||||
</button>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user