fdai7303
2 years ago
12 changed files with 477 additions and 0 deletions
-
43dist/bresenham.html
-
43dist/bresenhamsimple.html
-
42dist/dda.html
-
42dist/ddasimple.html
-
13src/04/bresenham.ts
-
24src/04/bresenhamsimple.ts
-
31src/04/dda.ts
-
28src/04/ddasimple.ts
-
64src/04/setup-bresenham.ts
-
40src/04/setup-bresenhamsimple.ts
-
68src/04/setup-dda.ts
-
39src/04/setup-ddasimple.ts
@ -0,0 +1,43 @@ |
|||
|
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - 2D - Bresenham</title> |
|||
<script type="text/javascript" src="bresenham.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Bresenham</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Implement the Bresenham algorithm to create a rotating line |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="col-sm-6 figure"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Reference image. The reference uses the build-in line drawing functionality |
|||
and is smoothed. Your line will look a bit more jagged. |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,43 @@ |
|||
|
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - 2D - Bresenham</title> |
|||
<script type="text/javascript" src="bresenhamsimple.bundle.js"></script> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Simple Bresenham</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Implement the Bresenham algorithm to create a single line |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="col-sm-6 figure"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Reference image. The reference uses the build-in line drawing functionality |
|||
and is smoothed. Your line will look a bit more jagged. |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,42 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - 2D - DDA</title> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
<script type="text/javascript" src="dda.bundle.js"></script> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">DDA</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Implement the DDA algorithm to create a rotating line |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="col-sm-6 figure"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Reference image. The reference uses the build-in line drawing functionality |
|||
and is smoothed. Your line will look a bit more jagged. |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,42 @@ |
|||
<!DOCTYPE html> |
|||
|
|||
<html lang="en"> |
|||
|
|||
<head> |
|||
<meta charset="UTF-8"> |
|||
<title>Graphische Datenverarbeitung - 2D - Simple DDA</title> |
|||
<link rel="icon" type="image/png" href="ai-logo.png"> |
|||
<script type="text/javascript" src="ddasimple.bundle.js"></script> |
|||
</head> |
|||
|
|||
<body> |
|||
<nav class="navbar navbar-light bg-light"> |
|||
<div class="container"> |
|||
<a class="navbar-brand" href="/index.html"> |
|||
<img src="ai-logo.png" width="30" height="30" class="d-inline-block align-top" alt=""> |
|||
Graphische Datenverarbeitung |
|||
</a> |
|||
<div class="navbar-brand">Simple DDA</div> |
|||
</div> |
|||
</nav> |
|||
<br> |
|||
<div class="container"> |
|||
<div class="row"> |
|||
<figure class="figure col-sm-6"> |
|||
<canvas id="result" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Implement the DDA algorithm to create an single line |
|||
</figcaption> |
|||
</figure> |
|||
<figure class="col-sm-6 figure"> |
|||
<canvas id="original" class="figure-img mx-auto d-block" width="300" height="300"></canvas> |
|||
<figcaption class="figure-caption text-center"> |
|||
Reference image. The reference uses the build-in line drawing functionality |
|||
and is smoothed. Your line will look a bit more jagged. |
|||
</figcaption> |
|||
</figure> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
|
|||
</html> |
@ -0,0 +1,13 @@ |
|||
/** |
|||
* Draws a line from pointA to pointB on the canvas |
|||
* with the Bresenham algorithm. |
|||
* @param {Uint8ClampedArray} data - The linearised pixel array |
|||
* @param {[number, number]} pointA - The start point of the line |
|||
* @param {[number, number]} pointB - The end point of the line |
|||
* @param {number} width - The width of the canvas |
|||
* @param {number} height - The height of the canvas |
|||
*/ |
|||
export function bresenham(data: Uint8ClampedArray, pointA: [number, number], pointB: [number, number], width: number, height: number) { |
|||
|
|||
// TODO: Adapt the C-implementation at https://de.wikipedia.org/wiki/Bresenham-Algorithmus#C-Implementierung
|
|||
} |
@ -0,0 +1,24 @@ |
|||
function setPixel(data: Uint8ClampedArray, x: number, y: number, width: number, height: number) { |
|||
|
|||
var index = (x + y * width) * 4; |
|||
data[index + 0] = 0; |
|||
data[index + 1] = 0; |
|||
data[index + 2] = 0; |
|||
data[index + 3] = 255; |
|||
} |
|||
|
|||
/** |
|||
* Draws a line from pointA to pointB on the canvas |
|||
* with the Bresenham algorithm. |
|||
* @param {Uint8ClampedArray} data - The linearised pixel array |
|||
* @param {[number, number]} pointA - The start point of the line |
|||
* @param {[number, number]} pointB - The end point of the line |
|||
* @param {number} width - The width of the canvas |
|||
* @param {number} height - The height of the canvas |
|||
*/ |
|||
export function bresenhamSimple(data: Uint8ClampedArray, pointA: [number, number], pointB: [number, number], width: number, height: number) { |
|||
|
|||
// TODO: 1. Calculate dx and dy and set the start position x and y
|
|||
// TODO: 2. Calculate the initial epsilon of the bresenham algorithm
|
|||
// TODO: 3. Go from pointA[0] to pointB[0], and update epsilon in each step as given in the bresenham algorithm. Increase y when necessary.
|
|||
} |
@ -0,0 +1,31 @@ |
|||
/** |
|||
* Draws a line from pointA to pointB on the canvas |
|||
* with the DDA algorithm. |
|||
* @param {Array.<number>} data - The linearised pixel array |
|||
* @param {Array.<number>} pointA - The start point of the line |
|||
* @param {Array.<number>} pointB - The end point of the line |
|||
* @param {number} width - The width of the canvas |
|||
* @param {number} height - The height of the canvas |
|||
*/ |
|||
export function dda( |
|||
data: Uint8ClampedArray, |
|||
pointA: [number, number], |
|||
pointB: [number, number], |
|||
width: number, height: number |
|||
) { |
|||
let setPixel = function ( |
|||
x: number, y: number, |
|||
data: Uint8ClampedArray, width: number |
|||
) { |
|||
data[4 * (width * y + x) + 0] = 0; |
|||
data[4 * (width * y + x) + 1] = 0; |
|||
data[4 * (width * y + x) + 2] = 0; |
|||
data[4 * (width * y + x) + 3] = 255; |
|||
} |
|||
|
|||
setPixel(pointA[0], pointA[1], data, width); |
|||
setPixel(pointB[0], pointB[1], data, width); |
|||
|
|||
// TODO: Distinguish between the main direction x and y.
|
|||
// TODO: Swap start and end points if necessary to reduce the number of cases.
|
|||
} |
@ -0,0 +1,28 @@ |
|||
function setPixel(data: Uint8ClampedArray, x: number, y: number, width: number, height: number) { |
|||
|
|||
var index = (x + y * width) * 4; |
|||
data[index + 0] = 0; |
|||
data[index + 1] = 0; |
|||
data[index + 2] = 0; |
|||
data[index + 3] = 255; |
|||
} |
|||
|
|||
/** |
|||
* Draws a line from pointA to pointB on the canvas |
|||
* with the DDA algorithm. |
|||
* @param {Array.<number>} data - The linearised pixel array |
|||
* @param {Array.<number>} pointA - The start point of the line |
|||
* @param {Array.<number>} pointB - The end point of the line |
|||
* @param {number} width - The width of the canvas |
|||
* @param {number} height - The height of the canvas |
|||
*/ |
|||
export function ddaSimple( |
|||
data: Uint8ClampedArray, |
|||
pointA: [number, number], |
|||
pointB: [number, number], |
|||
width: number, height: number |
|||
) { |
|||
// TODO: Calculcate the slope m for a line from pointA to pointB.
|
|||
// TODO: In this example, the main direction of the line is the x-direction.
|
|||
// TODO: Go from the x-coordinate of pointA (pointA[0]) to the x-coordinate of pointB (pointB[0]) and calculate the y-coordinate of the pixels in between.
|
|||
} |
@ -0,0 +1,64 @@ |
|||
|
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
import { bresenham } from './bresenham'; |
|||
|
|||
let canvasExample: HTMLCanvasElement; |
|||
let ctxExample: CanvasRenderingContext2D; |
|||
|
|||
function updateExample(pointA: [number, number], pointB: [number, number]) { |
|||
ctxExample.clearRect(0, 0, canvasExample.width, canvasExample.height); |
|||
ctxExample.beginPath(); |
|||
ctxExample.moveTo(pointA[0], pointA[1]); |
|||
ctxExample.lineTo(pointB[0], pointB[1]); |
|||
ctxExample.stroke(); |
|||
} |
|||
|
|||
let canvasBresenham: HTMLCanvasElement; |
|||
let ctxBresenham: CanvasRenderingContext2D; |
|||
let imageDataBresenham: ImageData; |
|||
|
|||
function updateBresenham(pointA: [number, number], pointB: [number, number]) { |
|||
const data = imageDataBresenham.data; |
|||
data.fill(0); |
|||
bresenham(data, pointA, pointB, canvasBresenham.width, canvasBresenham.height); |
|||
ctxBresenham.putImageData(imageDataBresenham, 0, 0); |
|||
} |
|||
|
|||
let t = 0; |
|||
|
|||
function calculatePoints(t: number): [[number, number], [number, number]] { |
|||
const pointA = [ |
|||
Math.round((Math.cos(t) + 1) / 2 * canvasBresenham.width), |
|||
Math.round((Math.sin(t) + 1) / 2 * canvasBresenham.height) |
|||
] as [number, number]; |
|||
const pointB = [ |
|||
Math.round((Math.cos(t + Math.PI) + 1) / 2 * canvasBresenham.width), |
|||
Math.round((Math.sin(t + Math.PI) + 1) / 2 * canvasBresenham.height) |
|||
] as [number, number]; |
|||
return [pointA, pointB]; |
|||
} |
|||
|
|||
function updateCanvas(timestamp: number) { |
|||
t += 0.01; |
|||
const points = calculatePoints(t); |
|||
updateExample(points[0], points[1]); |
|||
updateBresenham(points[0], points[1]); |
|||
window.requestAnimationFrame(updateCanvas); |
|||
} |
|||
|
|||
window.addEventListener('load', evt => { |
|||
canvasBresenham = document.getElementById("result") as HTMLCanvasElement; |
|||
if (canvasBresenham === null) |
|||
return; |
|||
canvasBresenham.height = canvasBresenham.width; |
|||
ctxBresenham = canvasBresenham.getContext("2d"); |
|||
imageDataBresenham = ctxBresenham.getImageData( |
|||
0, 0, canvasBresenham.width, canvasBresenham.height); |
|||
|
|||
canvasExample = document.getElementById("original") as HTMLCanvasElement; |
|||
canvasExample.height = canvasExample.width; |
|||
ctxExample = canvasExample.getContext("2d"); |
|||
|
|||
window.requestAnimationFrame(updateCanvas); |
|||
}); |
@ -0,0 +1,40 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
import { bresenhamSimple } from './bresenhamsimple'; |
|||
|
|||
var pointA: [ number, number ] = [ 0, 0 ]; |
|||
var pointB: [ number, number ] = [ 200, 100 ]; |
|||
|
|||
let canvasBresenham: HTMLCanvasElement; |
|||
let ctxBresenham: CanvasRenderingContext2D; |
|||
let imageDataBresenham: ImageData; |
|||
|
|||
function drawBresenham() { |
|||
|
|||
const data = imageDataBresenham.data; |
|||
data.fill(0); |
|||
bresenhamSimple(data, pointA, pointB, canvasBresenham.width, canvasBresenham.height); |
|||
ctxBresenham.putImageData(imageDataBresenham, 0, 0); |
|||
} |
|||
|
|||
window.addEventListener('load', evt => { |
|||
|
|||
canvasBresenham = document.getElementById("result") as HTMLCanvasElement; |
|||
if (canvasBresenham === null) |
|||
return; |
|||
|
|||
ctxBresenham = canvasBresenham.getContext("2d"); |
|||
imageDataBresenham = ctxBresenham.getImageData(0, 0, canvasBresenham.width, canvasBresenham.height); |
|||
|
|||
const canvasExample = document.getElementById("original") as HTMLCanvasElement; |
|||
canvasExample.height = canvasExample.width; |
|||
const ctxExample = canvasExample.getContext("2d"); |
|||
|
|||
ctxExample.clearRect(0, 0, canvasExample.width, canvasExample.height); |
|||
ctxExample.beginPath(); |
|||
ctxExample.moveTo(pointA[0], pointA[1]); |
|||
ctxExample.lineTo(pointB[0], pointB[1]); |
|||
ctxExample.stroke(); |
|||
|
|||
drawBresenham(); |
|||
}); |
@ -0,0 +1,68 @@ |
|||
|
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
import { dda } from './dda'; |
|||
|
|||
let canvasDDA: HTMLCanvasElement; |
|||
let ctxDDA: CanvasRenderingContext2D; |
|||
let imageDataDDA: ImageData; |
|||
|
|||
function updateDDA( |
|||
pointA: [number, number], |
|||
pointB: [number, number] |
|||
) { |
|||
const data = imageDataDDA.data; |
|||
data.fill(0); |
|||
dda(data, pointA, pointB, canvasDDA.width, canvasDDA.height); |
|||
ctxDDA.putImageData(imageDataDDA, 0, 0); |
|||
} |
|||
|
|||
let canvasExample: HTMLCanvasElement; |
|||
let ctxExample: CanvasRenderingContext2D; |
|||
|
|||
function updateExample( |
|||
pointA: [number, number], |
|||
pointB: [number, number] |
|||
) { |
|||
ctxExample.clearRect(0, 0, canvasExample.width, canvasExample.height); |
|||
ctxExample.beginPath(); |
|||
ctxExample.moveTo(pointA[0], pointA[1]); |
|||
ctxExample.lineTo(pointB[0], pointB[1]); |
|||
ctxExample.stroke(); |
|||
} |
|||
|
|||
let t = 0; |
|||
|
|||
function calculatePoints(t: number): [[number, number], [number, number]] { |
|||
const pointA = [ |
|||
Math.round((Math.cos(t) + 1) / 2 * canvasDDA.width), |
|||
Math.round((Math.sin(t) + 1) / 2 * canvasDDA.height) |
|||
] as [number, number]; |
|||
const pointB = [ |
|||
Math.round((Math.cos(t + Math.PI) + 1) / 2 * canvasDDA.width), |
|||
Math.round((Math.sin(t + Math.PI) + 1) / 2 * canvasDDA.height) |
|||
] as [number, number]; |
|||
return [pointA, pointB]; |
|||
} |
|||
|
|||
function updateCanvas(timestamp: number) { |
|||
t += 0.01; |
|||
const points = calculatePoints(t); |
|||
updateExample(points[0], points[1]); |
|||
updateDDA(points[0], points[1]); |
|||
window.requestAnimationFrame(updateCanvas); |
|||
} |
|||
|
|||
window.addEventListener('load', evt => { |
|||
canvasDDA = document.getElementById("result") as HTMLCanvasElement; |
|||
if (canvasDDA === null) |
|||
return; |
|||
ctxDDA = canvasDDA.getContext("2d"); |
|||
imageDataDDA = ctxDDA.getImageData(0, 0, canvasDDA.width, canvasDDA.height); |
|||
|
|||
canvasExample = document.getElementById("original") as HTMLCanvasElement; |
|||
canvasExample.height = canvasExample.width; |
|||
ctxExample = canvasExample.getContext("2d"); |
|||
|
|||
window.requestAnimationFrame(updateCanvas); |
|||
}); |
@ -0,0 +1,39 @@ |
|||
import 'bootstrap'; |
|||
import 'bootstrap/scss/bootstrap.scss'; |
|||
import { ddaSimple } from './ddasimple'; |
|||
|
|||
var pointA: [ number, number ] = [ 0, 0 ]; |
|||
var pointB: [ number, number ] = [ 200, 100 ]; |
|||
|
|||
let canvasDDA: HTMLCanvasElement; |
|||
let ctxDDA: CanvasRenderingContext2D; |
|||
let imageDataDDA: ImageData; |
|||
|
|||
function drawDDA() { |
|||
|
|||
const data = imageDataDDA.data; |
|||
data.fill(0); |
|||
ddaSimple(data, pointA, pointB, canvasDDA.width, canvasDDA.height); |
|||
ctxDDA.putImageData(imageDataDDA, 0, 0); |
|||
} |
|||
|
|||
window.addEventListener('load', evt => { |
|||
|
|||
canvasDDA = document.getElementById("result") as HTMLCanvasElement; |
|||
if (canvasDDA === null) |
|||
return; |
|||
ctxDDA = canvasDDA.getContext("2d"); |
|||
imageDataDDA = ctxDDA.getImageData(0, 0, canvasDDA.width, canvasDDA.height); |
|||
|
|||
const canvasExample = document.getElementById("original") as HTMLCanvasElement; |
|||
canvasExample.height = canvasExample.width; |
|||
const ctxExample = canvasExample.getContext("2d"); |
|||
|
|||
ctxExample.clearRect(0, 0, canvasExample.width, canvasExample.height); |
|||
ctxExample.beginPath(); |
|||
ctxExample.moveTo(pointA[0], pointA[1]); |
|||
ctxExample.lineTo(pointB[0], pointB[1]); |
|||
ctxExample.stroke(); |
|||
|
|||
drawDDA(); |
|||
}); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue