Skip to content
Snippets Groups Projects
Commit 7e5f6b57 authored by Yuriy Maksymets's avatar Yuriy Maksymets
Browse files

Fixed tests to match new interfaces, minor refactor

parent 15868e64
No related branches found
No related tags found
No related merge requests found
import recognizeFromPoints, {
Shapes,
computeMatrixCoefficients,
} from "../src/shapes"
import recognizeFromPoints, { Shapes } from "../src/shapes"
describe("shape recognition", () => {
describe("general", () => {
......@@ -12,41 +9,30 @@ describe("shape recognition", () => {
})
})
describe("matrix coefficients", () => {
test("should compute coefficients correctly", () => {
const points = [[0, 0], [0, 5], [0, 10], [10, 5]]
const coefficients = computeMatrixCoefficients(points)
expect(coefficients).toStrictEqual([
[1 / 4, 1 / 4, 1 / 4],
[0, 0, 0],
[0, 1 / 4, 0],
])
})
})
describe("lines", () => {
test("should recognize a simple horizontal line", () => {
const points = [[0, 0], [100, 0]]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBe(0)
expect(result.firstPoint).toStrictEqual([0, 0])
expect(result.lastPoint).toStrictEqual([100, 0])
})
test("should recognize a simple vertical line", () => {
const points = [[0, 50], [0, -100]]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBe(90)
expect(result.firstPoint).toStrictEqual([0, 50])
expect(result.lastPoint).toStrictEqual([0, -100])
})
test("should recognize a slightly curve horizontal line", () => {
const points = [[0, 0], [30, 5], [100, 0]]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBe(0)
})
test("should not recognize a really curved horizontal line", () => {
test("should not recognize a heavily curved horizontal line", () => {
const points = [[0, 0], [30, 30], [100, -4]]
const result = recognizeFromPoints(points)
expect(result.shape).not.toBe(Shapes.line)
......@@ -72,7 +58,6 @@ describe("shape recognition", () => {
]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBe(0)
})
test("should recognize a long vertical line", () => {
......@@ -115,7 +100,6 @@ describe("shape recognition", () => {
]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBe(90)
})
test("should recognize a line at 20 degrees", () => {
......@@ -192,7 +176,6 @@ describe("shape recognition", () => {
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.line)
expect(result.angle).toBeGreaterThan(12)
})
test("should recognize line 1", () => {
......@@ -328,12 +311,6 @@ describe("shape recognition", () => {
describe("rectangles", () => {
test("should recognize simple rectangle", () => {
const points = [[-10, -10], [10, -10], [10, 10], [-10, 10]]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.rectangle)
})
test("should recognize rectangle with many points", () => {
const points = [
[0, 0],
[5, 0],
......@@ -374,7 +351,15 @@ describe("shape recognition", () => {
})
test("should recognize almost-closed rectangle", () => {
const points = [[-10, -10], [10, -10], [10, 10], [-9, 9]]
const points = [
[0, 0],
[5, 0],
[10, 0],
[10, 5],
[10, 10],
[5, 10],
[0, 8],
]
const result = recognizeFromPoints(points)
expect(result.shape).toBe(Shapes.rectangle)
})
......
......@@ -33,6 +33,21 @@ const getPressureFactor = (pressure) => {
return a * pressure ** 2 + b * pressure + c
}
const PREDICTED_POINT_COLOR = "#00000055"
function faintPoint(x, y) {
return [x, y, 1, PREDICTED_POINT_COLOR]
}
function attributedPoint(x, y, pressure = 0) {
return [
x,
y,
toolSelection.getStrokeRadius() * getPressureFactor(pressure),
toolSelection.getStrokeColour(),
]
}
let room = null
const humanHasher = new humanhash()
......@@ -148,26 +163,13 @@ const onRoomConnect = (room_) => {
)
}
function faintPoint(x, y) {
return [x, y, 1, "#00000033"]
}
function attributedPoint(x, y, pressure = 0) {
return [
x,
y,
toolSelection.getStrokeRadius() * getPressureFactor(pressure),
toolSelection.getStrokeColour(),
]
}
function getRecognizedShapePoints(points) {
const recognizedShape = recognizeFromPoints(points)
if (!recognizedShape.shape) return undefined
switch (recognizedShape.shape) {
case Shapes.line: {
const [x, y] = points[0]
const p1 = [x, y]
const p1 = recognizedShape.firstPoint
const p2 = recognizedShape.lastPoint
return [p1, p2]
}
......@@ -175,6 +177,7 @@ function getRecognizedShapePoints(points) {
return recognizedShape.boundingPoints
}
}
return undefined
}
......
......@@ -7,7 +7,12 @@ const RECT_MATRIX_CENTER_RATIO = 0.65
const RECT_THRESHOLD_CENTER = 0
const RECT_THRESHOLD_SIDE_VARIANCE = 0.25
function getDistance([x0, y0], [x1, y1]) {
const MIN_RECT_POINTS = 4
const MIN_LINE_POINTS = 2
function getDistance(p1, p2) {
if (!(p1 && p2)) return 0
const [[x0, y0], [x1, y1]] = [p1, p2]
return Math.hypot(x1 - x0, y1 - y0)
}
......@@ -85,12 +90,13 @@ export function computeMatrixCoefficients(points, boundingRect) {
const xBounds = matrixBoundsArray(minX, maxX)
const yBounds = matrixBoundsArray(minY, maxY)
const clusters = computeClusters(points, xBounds, yBounds)
console.log(clusters)
const coefficients = clusterCoefficients(clusters, points)
return coefficients
}
function couldBeRect(points) {
if (points.length < 4) return false
if (points.length < MIN_RECT_POINTS) return false
const boundingRect = boundingCoords(points)
const matrixCoefficients = computeMatrixCoefficients(points, boundingRect)
......@@ -115,22 +121,23 @@ function couldBeRect(points) {
}
function couldBeLine(points) {
if (points.length < 2) return false
if (points.length < MIN_LINE_POINTS) return false
const vectorThreshold = Math.floor(
points.length * VECTOR_LEN_THRESHOLD_FRACTION,
)
const pivot = points[0]
let cumulativeThreshold = 0
for (let i = 2; i < points.length; i++) {
const p1 = points[i - 1]
const p2 = points[i]
const d1 = diffVector(pivot, p1)
const d2 = diffVector(p1, p2)
const d2Len = vectorLength(d2)
for (let i = 2; i < points.length; i++) {
const prev = points[i - 1]
const curr = points[i]
const d1 = diffVector(pivot, prev)
const d2 = diffVector(prev, curr)
const angle = angleBetweenVectors(d1, d2)
if (Math.abs(angle) > LINE_ANGLE_THRESHOLD) {
const d2Len = vectorLength(d2)
if (cumulativeThreshold < vectorThreshold && d2Len < vectorThreshold) {
cumulativeThreshold += d2Len
continue
......@@ -141,10 +148,9 @@ function couldBeLine(points) {
return true
}
function recognizeRect(points, rectDetectionData) {
function recognizedRect(_, rectDetectionData) {
const { minX, minY, maxX, maxY } = rectDetectionData.boundingRect
return {
boundingRect: rectDetectionData.boundingRect,
boundingPoints: [
[minX, minY],
[minX, maxY],
......@@ -153,29 +159,26 @@ function recognizeRect(points, rectDetectionData) {
[minX, minY],
],
shape: Shapes.rectangle,
points,
}
}
function recognizeLine(points) {
function recognizedLine(points) {
const [p1, p2] = [points[0], points[points.length - 1]]
const angle =
(angleBetweenVectors(diffVector(p2, p1), [1, 0]) / Math.PI) * 180
return {
shape: Shapes.line,
angle,
points,
length: getDistance(p1, p2),
// Take only [x, y] from the whole point tuple
lastPoint: p2.slice(0, 2),
firstPoint: p1.slice(0, 2),
}
}
function recognizeFromPoints(points) {
const rectDetectData = couldBeRect(points)
if (rectDetectData) {
return recognizeRect(points, rectDetectData)
return recognizedRect(points, rectDetectData)
} else if (couldBeLine(points)) {
return recognizeLine(points)
return recognizedLine(points)
}
return {}
......
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