From 41e2851b25bbd12964307821becbf1bb3c923b48 Mon Sep 17 00:00:00 2001 From: Yuriy Maksymets <iurii.maksymets@gmail.com> Date: Sun, 10 Nov 2019 17:40:09 +0000 Subject: [PATCH] Recognizing lines with angles (test) --- __tests__/shape.test.js | 151 +++++++++++++++++++++++++++++++++++++++- src/shapes.js | 23 ++++-- 2 files changed, 167 insertions(+), 7 deletions(-) diff --git a/__tests__/shape.test.js b/__tests__/shape.test.js index 201a159..db3d23f 100644 --- a/__tests__/shape.test.js +++ b/__tests__/shape.test.js @@ -1,4 +1,4 @@ -import recognizeFromPoints, { Shapes } from "../src/shapes" +import recognizeFromPoints, { Shapes, LineDirections } from "../src/shapes" describe("shape recognition", () => { describe("general", () => { @@ -14,22 +14,171 @@ describe("shape recognition", () => { const points = [[0, 0], [100, 0]] const result = recognizeFromPoints(points) expect(result.shape).toBe(Shapes.line) + expect(result.direction).toBe(LineDirections.h) }) + 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.direction).toBe(LineDirections.v) }) + test("should recognize a slightly curve horizontal line", () => { const points = [[0, 0], [30, 5], [100, 2]] const result = recognizeFromPoints(points) expect(result.shape).toBe(Shapes.line) + expect(result.direction).toBe(LineDirections.h) }) + test("should not recognize a really curved horizontal line", () => { const points = [[0, 0], [30, 30], [100, -4]] const result = recognizeFromPoints(points) expect(result.shape).not.toBe(Shapes.line) }) + + test("should recognize a long horizontal line", () => { + const points = [ + [48.675496688741724, 197.8062913907285], + [50.66225165562914, 197.8062913907285], + [53.64238410596026, 197.8062913907285], + [57.6158940397351, 197.8062913907285], + [61.58940397350993, 197.8062913907285], + [66.55629139072848, 197.8062913907285], + [71.52317880794702, 197.8062913907285], + [76.49006622516558, 197.8062913907285], + [77.48344370860927, 197.8062913907285], + [82.45033112582782, 197.8062913907285], + [84.43708609271523, 197.8062913907285], + [87.41721854304636, 197.8062913907285], + [88.41059602649007, 197.8062913907285], + [88.41059602649007, 197.8062913907285], + [89.40397350993378, 197.8062913907285], + ] + const result = recognizeFromPoints(points) + expect(result.shape).toBe(Shapes.line) + expect(result.direction).toBe(LineDirections.h) + }) + + test("should recognize a long vertical line", () => { + const points = [ + [218.54304635761588, 84.56125827814569], + [218.54304635761588, 86.54801324503312], + [218.54304635761588, 87.54139072847681], + [218.54304635761588, 88.53476821192052], + [218.54304635761588, 90.52152317880794], + [218.54304635761588, 91.51490066225165], + [218.54304635761588, 92.50827814569537], + [218.54304635761588, 93.50165562913908], + [218.54304635761588, 94.49503311258277], + [218.54304635761588, 94.49503311258277], + [218.54304635761588, 95.4884105960265], + [218.54304635761588, 96.4817880794702], + [218.54304635761588, 97.4751655629139], + [218.54304635761588, 98.46854304635761], + [218.54304635761588, 100.45529801324503], + [218.54304635761588, 101.44867549668874], + [218.54304635761588, 103.43543046357617], + [218.54304635761588, 105.42218543046357], + [218.54304635761588, 108.4023178807947], + [218.54304635761588, 110.38907284768212], + [218.54304635761588, 112.37582781456953], + [218.54304635761588, 114.36258278145695], + [218.54304635761588, 116.34933774834438], + [218.54304635761588, 118.33609271523179], + [218.54304635761588, 119.32947019867551], + [218.54304635761588, 120.3228476821192], + [218.54304635761588, 122.30960264900662], + [218.54304635761588, 123.30298013245033], + [218.54304635761588, 124.29635761589404], + [218.54304635761588, 125.28973509933775], + [218.54304635761588, 125.28973509933775], + [218.54304635761588, 125.28973509933775], + [218.54304635761588, 126.28311258278147], + [218.54304635761588, 126.28311258278147], + [218.54304635761588, 127.27649006622516], + ] + const result = recognizeFromPoints(points) + expect(result.shape).toBe(Shapes.line) + expect(result.direction).toBe(LineDirections.v) + }) + + test("should recognize a line at 20 degrees", () => { + const points = [ + [34.7682119205298, 268.3360927152318], + [34.7682119205298, 268.3360927152318], + [36.75496688741722, 268.3360927152318], + [37.74834437086093, 268.3360927152318], + [38.741721854304636, 268.3360927152318], + [39.735099337748345, 268.3360927152318], + [40.728476821192054, 268.3360927152318], + [41.721854304635755, 268.3360927152318], + [42.71523178807947, 268.3360927152318], + [43.70860927152318, 268.3360927152318], + [43.70860927152318, 268.3360927152318], + [44.70198675496689, 268.3360927152318], + [44.70198675496689, 268.3360927152318], + [45.6953642384106, 267.3427152317881], + [45.6953642384106, 267.3427152317881], + [46.6887417218543, 267.3427152317881], + [47.682119205298015, 267.3427152317881], + [48.675496688741724, 266.34933774834434], + [48.675496688741724, 266.34933774834434], + [49.66887417218543, 266.34933774834434], + [50.66225165562914, 266.34933774834434], + [51.65562913907284, 265.35596026490066], + [52.64900662251656, 265.35596026490066], + [52.64900662251656, 265.35596026490066], + [53.64238410596026, 265.35596026490066], + [54.63576158940397, 264.362582781457], + [54.63576158940397, 264.362582781457], + [55.629139072847686, 264.362582781457], + [55.629139072847686, 264.362582781457], + [57.6158940397351, 263.36920529801324], + [57.6158940397351, 263.36920529801324], + [58.609271523178805, 263.36920529801324], + [58.609271523178805, 263.36920529801324], + [59.602649006622514, 262.37582781456956], + [60.59602649006623, 262.37582781456956], + [61.58940397350993, 262.37582781456956], + [62.58278145695365, 261.3824503311258], + [63.57615894039735, 261.3824503311258], + [64.56953642384106, 260.3890728476821], + [66.55629139072848, 259.3956953642384], + [67.54966887417218, 259.3956953642384], + [68.54304635761589, 259.3956953642384], + [69.5364238410596, 258.4023178807947], + [69.5364238410596, 258.4023178807947], + [70.52980132450331, 258.4023178807947], + [71.52317880794702, 258.4023178807947], + [71.52317880794702, 257.408940397351], + [71.52317880794702, 257.408940397351], + [72.51655629139073, 257.408940397351], + [72.51655629139073, 257.408940397351], + [72.51655629139073, 257.408940397351], + [73.50993377483444, 257.408940397351], + [73.50993377483444, 257.408940397351], + [73.50993377483444, 257.408940397351], + [74.50331125827815, 257.408940397351], + [76.49006622516558, 257.408940397351], + [77.48344370860927, 257.408940397351], + [79.47019867549669, 256.4155629139073], + [80.4635761589404, 256.4155629139073], + [82.45033112582782, 255.42218543046357], + [83.44370860927151, 255.42218543046357], + [84.43708609271523, 255.42218543046357], + [85.43046357615894, 255.42218543046357], + [85.43046357615894, 254.42880794701986], + [86.42384105960264, 254.42880794701986], + [86.42384105960264, 254.42880794701986], + [87.41721854304636, 254.42880794701986], + [87.41721854304636, 254.42880794701986], + ] + + const result = recognizeFromPoints(points) + expect(result.shape).toBe(Shapes.line) + expect(result.direction).toBe(LineDirections.d20) + }) }) describe("rectangles", () => { diff --git a/src/shapes.js b/src/shapes.js index 72f8e71..4611b73 100644 --- a/src/shapes.js +++ b/src/shapes.js @@ -9,7 +9,7 @@ function sin(a) { } const rhoStep = 5 -const angleStep = 90 +const angleStep = 10 const numAngleCells = 180 / angleStep const rhoMax = 1000 @@ -32,11 +32,7 @@ function findMaxInHough(accum, threshold) { bestTheta *= angleStep if (max > threshold) { - if (bestTheta === 90) { - return 90 - } else { - return 0 - } + return bestTheta } return undefined } @@ -67,6 +63,7 @@ function recognizeFromPoints(points) { if (angle !== undefined) { return { shape: Shapes.line, + direction: getDirection(angle), points, } } @@ -74,6 +71,20 @@ function recognizeFromPoints(points) { return {} } +const dirMap = { 0: "v", 90: "h", 70: "d20" } + +function getDirection(angle) { + const map = dirMap[angle] + if (map == undefined) return angle + return LineDirections[map] +} + +export const LineDirections = { + v: "v", + h: "h", + d20: "20", +} + export const Shapes = { rectangle: "rect", line: "line", -- GitLab