Skip to content
Snippets Groups Projects
Commit df3ab4a4 authored by Nayeem Rahman's avatar Nayeem Rahman
Browse files

Improve pressure application on radius

Also:
- Interpolate with curveBasis instead of curveLinear
- Increase the default stroke radius to 5 from 1
parent f46156fc
No related branches found
No related tags found
No related merge requests found
......@@ -2,7 +2,7 @@
// Emit input events and receive draw calls seperately - these must be piped
// together externally if desired.
import { line, curveLinear } from "d3-shape"
import { line, curveBasis } from "d3-shape"
import { canvas } from "./elements.js"
......@@ -12,22 +12,20 @@ const SVG_URL = "http://www.w3.org/2000/svg"
const lineFn = line()
.x((d) => d[0])
.y((d) => d[1])
.curve(curveLinear)
.curve(curveBasis)
const pathGroupElems = new Map()
let stroke_colour = "blue"
export let stroke_radius = 1
export const MIN_STROKE_RADIUS = 0.1
export const MAX_STROKE_RADIUS = 3.9
let strokeColour = "blue"
let strokeRadius = 5
const MAX_POINT_DISTANCE = 5
const MAX_PRESSURE_DELTA = 0.05
const MAX_RADIUS_DELTA = 0.05
// Interpolate a path so that:
// - The distance between two adjacent points is capped at MAX_POINT_DISTANCE.
// - The pressure delta between two adjacent points is capped at
// MAX_PRESSURE_DELTA
// - The radius delta between two adjacent points is capped at
// MAX_RADIUS_DELTA
// If paths are too choppy, try decreasing these constants.
const smoothPath = ([...path]) => {
// Apply MAX_POINT_DISTANCE.
......@@ -51,13 +49,12 @@ const smoothPath = ([...path]) => {
i += newPoints.length
}
// Apply MAX_PRESSURE_DELTA.
// Apply MAX_RADIUS_DELTA.
for (let i = 1; i < path.length; i++) {
const dx = path[i][0] - path[i - 1][0]
const dy = path[i][1] - path[i - 1][1]
const dw = path[i][2] - path[i - 1][2]
const normdw = dw / Math.max(0.05, Math.max(path[i][2], path[i - 1][2]))
const segmentsToSplit = Math.ceil(normdw / MAX_PRESSURE_DELTA)
const segmentsToSplit = Math.ceil(dw / MAX_RADIUS_DELTA)
const newPoints = []
for (let j = 1; j < segmentsToSplit; j++) {
newPoints.push([
......@@ -173,24 +170,36 @@ canvas.addEventListener("pointermove", dispatchPointerEvent("strokemove"))
canvas.addEventListener("touchmove", (e) => e.preventDefault())
export function setStrokeColour(colour) {
stroke_colour = colour
strokeColour = colour
}
export function getStrokeColour() {
return stroke_colour
return strokeColour
}
export function setStrokeRadius(radius) {
stroke_radius = radius
const MIN_PRESSURE_FACTOR = 0.1
const MAX_PRESSURE_FACTOR = 1.5
// This is a quadratic such that:
// - getPressureFactor(0.0) = MIN_PRESSURE_FACTOR
// - getPressureFactor(0.5) = 1.0
// - getPressureFactor(1.0) = MAX_PRESSURE_FACTOR
// For sensible results, maintain that:
// - 0.0 <= MIN_PRESSURE_FACTOR <= 1.0
// - 1.0 <= MAX_PRESSURE_FACTOR
// For intuitive results, maintain that:
// - MAX_PRESSURE_FACTOR <= ~2.0
const getPressureFactor = (pressure) => {
const a = 2 * (MAX_PRESSURE_FACTOR + MIN_PRESSURE_FACTOR) - 4
const b = -MAX_PRESSURE_FACTOR - 3 * MIN_PRESSURE_FACTOR + 4
const c = MIN_PRESSURE_FACTOR
return a * pressure ** 2 + b * pressure + c
}
const calculateStrokeRadius = (pressure, radius) => {
return (
MIN_STROKE_RADIUS +
(radius + pressure) * (MAX_STROKE_RADIUS - MIN_STROKE_RADIUS)
)
export function getStrokeRadius(pressure) {
return strokeRadius * getPressureFactor(pressure)
}
export function getStrokeRadius(pressure) {
return calculateStrokeRadius(pressure, stroke_radius)
export function setStrokeRadius(radius) {
strokeRadius = radius
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment