Skip to content

Commit

Permalink
added new shot detection algorithm
Browse files Browse the repository at this point in the history
  • Loading branch information
dbecker1 committed Jul 6, 2020
1 parent 7ec20cf commit 9df2788
Show file tree
Hide file tree
Showing 13 changed files with 274 additions and 331 deletions.
377 changes: 191 additions & 186 deletions .idea/workspace.xml

Large diffs are not rendered by default.

60 changes: 19 additions & 41 deletions src/app/hitPointDetectionMiddleware.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,51 +17,29 @@ const checkBoundaries = (target, pointCoordinates) => {
return true
}


export const detectHitPoints = store => next => action => {
if (action.type === addShot.type) {
try {
const state = store.getState();
const currentTargets = state.targets;
for (let i in currentTargets) {
const currentTarget = currentTargets[i];
if (checkBoundaries(currentTarget, action.payload.center)) {
const target = TargetUtil.getTargetByName(currentTarget.name)
const canvas = document.createElement("canvas");
canvas.width = currentTarget.width;
canvas.height = currentTarget.height;
const scaleTarget = currentTarget.requestedScaleRatio;
const ctx = canvas.getContext('2d');
const point = {
x: (action.payload.center.x - currentTarget.x) / scaleTarget,
y: (action.payload.center.y - currentTarget.y) / scaleTarget
}
if (target.hasOwnProperty("scoringZones")) {
let lowestPriority = Infinity;
for (let j in target.scoringZones) {
const zone = target.scoringZones[j];
const path = new Path2D(zone.path)
//ctx.moveTo(0, 0);
ctx.stroke(path);
if (ctx.isPointInPath(path, point.x, point.y)) {
if (zone.priority < lowestPriority) {
action.payload.score = {
pointValue: zone.pointValue,
name: zone.name,
targetId: currentTarget.id
};
lowestPriority = zone.priority;
}
}
}
}
// Uncommenting this can be helpful for debugging
// ctx.beginPath();
// ctx.arc(point.x, point.y, 5, 0, 2 * Math.PI, false);
// ctx.fillStyle = 'green';
// ctx.fill();
// const text = document.createTextNode("scale: " + scaleTarget + " x: " + point.x + " y: " + point.y);
// document.getElementById("canvashere").appendChild(text);
// document.getElementById("canvashere").appendChild(canvas);
const popupWindow = window.open('', 'com_sharpshooter_projectorwindow');

const relativeX = action.payload.center.x + state.projector.canvasX
const relativeY = action.payload.center.y + state.projector.canvasY
const elem = popupWindow.document.elementFromPoint(relativeX, relativeY)
const parentElem = elem.parentElement
console.log(parentElem);
if (parentElem.hasAttribute("data-target-id") && elem.hasAttribute("data-name")) {
const pathDataName = elem.getAttribute("data-name")
const targetId = parentElem.getAttribute("data-target-id")
const targetRecord = state.targets.filter(a => {return a.id === targetId})[0];

const baseTarget = TargetUtil.getTargetByName(targetRecord.name)
const scoreZone = baseTarget.scoringZones.filter(a => {return a.pathDataName === pathDataName})[0]
action.payload.score = {
pointValue: scoreZone.pointValue,
name: scoreZone.name,
targetId: targetId
}
}
} catch (e) {
Expand Down
8 changes: 7 additions & 1 deletion src/app/slices/projectorSlice.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const projectorSlice = createSlice({
resized: false,
canvasWidth: 0,
canvasHeight: 0,
canvasX: null,
canvasY: null,
nonTargetElements: [],
},
reducers: {
Expand All @@ -15,6 +17,10 @@ export const projectorSlice = createSlice({
state.canvasHeight = action.payload.canvasHeight;
state.canvasWidth = action.payload.canvasWidth;
},
setCoordinates: (state, action) => {
state.canvasX = action.payload.canvasX;
state.canvasY = action.payload.canvasY;
},
addNonTargetElement: (state, action) => {
state.nonTargetElements.push(action.payload)
},
Expand All @@ -30,6 +36,6 @@ export const projectorSlice = createSlice({
},
});

export const { finishResize, addNonTargetElement, removeNonTargetElementByName, wipeNonTargetElements, launchProjector } = projectorSlice.actions;
export const { finishResize, addNonTargetElement, removeNonTargetElementByName, wipeNonTargetElements, launchProjector, setCoordinates } = projectorSlice.actions;

export default projectorSlice.reducer;
4 changes: 4 additions & 0 deletions src/components/TargetCanvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ class TargetCanvas extends React.Component{
let rect = this.canvasRef.current.getBoundingClientRect();
let x = e.clientX - rect.left;
let y = e.clientY - rect.top;

// const elem = document.elementFromPoint(e.clientX, e.clientY)
// console.log(elem)
this.props.onClick({
x: x,
y: y
Expand All @@ -43,6 +46,7 @@ class TargetCanvas extends React.Component{
y={value.y}
width={value.width}
height={value.height}
targetId={value.id}
key={index}/>
})}
{this.props.nonTargetElements.map((value, index) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class StandardShoot extends React.Component {
if (this.hasOwnProperty("interval"))
clearInterval(this.interval)

const fps = 40;
const fps = 20;
let delay = 1000 / fps;
this.interval = setInterval(() => {
this.props.tickTargets()
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/components/mainScreen/shootingModes/svgs/Bullseye.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from 'react';

const Bullseye = ({x=0, y=0, width=251, height=251}) => {
const Bullseye = ({x=0, y=0, width=251, height=251, targetId= null}) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 251 251" x={x} y={y} width={width} height={height}>
<g id="Bullseye">
<g id="Bullseye" data-target-id={targetId}>
<path id="_4-ring" data-name="4-ring" style={{stroke: "#000", strokeMiterlimit: 10, fill: "#000"}}
d="M250.5,125.5A125,125,0,1,1,125.5.5,125,125,0,0,1,250.5,125.5Z"/>
<path id="_6-ring" data-name="6-ring" style={{stroke: "#000", strokeMiterlimit: 10, fill: "#0071bc"}}
Expand Down
6 changes: 3 additions & 3 deletions src/components/mainScreen/shootingModes/svgs/TreePlate.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

const TreePlate = ({x=0, y=0, width=69, height=59}) => {
const TreePlate = ({x=0, y=0, width=69, height=59, targetId= null}) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69 59" x={x} y={y} width={width} height={height}>
<g id="DuelingTreeBase">
<path style={{fill: "#ccc", stroke: "#ccc", strokeMiterlimit: 10}} d="M68.5,17.5v25H55.42a29,29,0,1,1,.48-25Z"/>
<g id="DuelingTreeBase" data-target-id={targetId}>
<path data-name="plate" style={{fill: "#ccc", stroke: "#ccc", strokeMiterlimit: 10}} d="M68.5,17.5v25H55.42a29,29,0,1,1,.48-25Z"/>
</g>
</svg>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import React from 'react';

const TreePlate = ({x=0, y=0, width=69, height=59}) => {
const TreePlate = ({x=0, y=0, width=69, height=59, targetId= null}) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 69 59" x={x} y={y} width={width} height={height}>
<g id="DuelingTreeBase">
<path style={{fill: "#ccc", stroke: "#ccc", strokeMiterlimit: 10}} d="M.5,41.5v-25H13.58a29,29,0,1,1-.48,25Z"/>
<g id="DuelingTreeBase" data-target-id={targetId}>
<path data-name="plate-flipped" style={{fill: "#ccc", stroke: "#ccc", strokeMiterlimit: 10}} d="M.5,41.5v-25H13.58a29,29,0,1,1-.48,25Z"/>
</g>
</svg>
)
Expand Down
14 changes: 7 additions & 7 deletions src/components/mainScreen/shootingModes/svgs/USPSA.js
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import React from 'react';

const USPSA = ({x=0, y=0, width=237, height=377.82}) => {
const USPSA = ({x=0, y=0, width=237, height=377.82, targetId = null}) => {
return (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 237 377.82" x={x} y={y} width={width} height={height}>
<g id="USPSA">
<path id="D-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
<g id="USPSA" data-target-id={targetId}>
<path id="D-target" data-name="D-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
d="M40,377.57.25,300.17,2.4,115.27l-.34-6.1,30.1-30.1,5.72-5.72H197l7.86,6.25,30.1,30.1-.34,6.11,2.15,184.9-2.45,4.78-36.25,72.08H40Z"/>
<path id="C-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
<path id="C-target" data-name="C-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
d="M68.74,300.71,43.79,242.87l1.35-138.19-.22-4.56L63.8,77.62l3.59-4.27h99.8L172.12,78,191,100.52l-.21,4.56,1.35,138.19-1.54,3.57-22.74,53.87H68.74Z"/>
<path id="A-body-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
<path id="A-body-target" data-name="A-body-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
d="M148.75,246.43H89.46a6.37,6.37,0,0,1-6.37-6.37V116.27a6.37,6.37,0,0,1,6.37-6.37h59.29a6.37,6.37,0,0,1,6.37,6.37V240.06A6.38,6.38,0,0,1,148.75,246.43Z"/>
<path id="B-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}} d="M160.43,73.35H75.5V.25h84.93Z"/>
<path id="A-head-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
<path id="B-target" data-name="B-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}} d="M160.43,73.35H75.5V.25h84.93Z"/>
<path id="A-head-target" data-name="A-head-target" style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
d="M138.52,43.25H99.68a6.38,6.38,0,0,1-6.38-6.38V22.76a6.38,6.38,0,0,1,6.38-6.38h38.84a6.37,6.37,0,0,1,6.38,6.38V36.87A6.38,6.38,0,0,1,138.52,43.25Z"/>
<g id="A">
<path style={{fill:"#fff", stroke: "#000", strokeMiterlimit: 10, strokeWidth: "0.5px"}}
Expand Down
52 changes: 17 additions & 35 deletions src/components/mainScreen/shootingModes/targets.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,7 @@ import TreePlate from "./svgs/TreePlate"
import TreePlateFlipped from "./svgs/TreePlateFlipped"
import USPSA from "./svgs/USPSA"
import Bullseye from "./svgs/Bullseye"
//In order to create scoring zones, take your SVG image and view the raw xml of it. Each zone should be defined by a
//single <path> tag. Take the "d" attribute of this tag (the one that defines the path) and put the resultant string
// in for the "path" of the scoringZone

export let basic_silhouette = {
name: "basic_silhouette",
fileName: "basic_silhouette.svg",
Expand All @@ -18,33 +16,28 @@ export let basic_silhouette = {
scoringZones: [
{
name: "Bullseye",
pathDataName: "10-ring",
pointValue: 10,
path: "M119.72,224.91v15.34a8.57,8.57,0,0,1-.11,1.44,11.06,11.06,0,0,1-21.78,0,8.57,8.57,0,0,1-.11-1.44V224.91c0-.16,0-.32,0-.48a11,11,0,0,1,22,0C119.72,224.59,119.72,224.75,119.72,224.91Z",
priority: 1
},
{
name: "9",
pathDataName: "9-ring",
pointValue: 9,
path: "M128.72,218.68v28.76c0,.32,0,.65,0,1-.52,10.15-9.26,18.22-20,18.22s-19.45-8.07-20-18.22c0-.31,0-.64,0-1V218.68c0-10.6,9-19.18,20-19.18S128.72,208.08,128.72,218.68Z",
priority: 2
},
{
name: "8",
pathDataName: "8-ring",
pointValue: 8,
path: "M148.22,207.17V259c0,21.18-17.91,38.35-40,38.35s-40-17.17-40-38.35V207.17c0-21.18,17.91-38.35,40-38.35S148.22,186,148.22,207.17Z",
priority: 3
},
{
name: "7",
pathDataName: "7-ring",
pointValue: 7,
path: "M168.72,194.71v76.7c0,31.78-26.86,57.53-60,57.53s-60-25.75-60-57.53v-76.7c0-31.78,26.86-57.53,60-57.53S168.72,162.93,168.72,194.71Z",
priority: 4
},
{
name: "6",
pathDataName: "6-ring",
pointValue: 6,
path: "M187.72,180.33V284.84c0,41.83-35.37,75.74-79,75.74s-79-33.91-79-75.74V180.33c0-41.84,35.37-75.75,79-75.75S187.72,138.49,187.72,180.33Z",
priority: 5
}
]
};
Expand All @@ -61,33 +54,28 @@ export let uspsa = {
scoringZones: [
{
name: "A - Head",
pathDataName: "A-head-target",
pointValue: 5,
path: "M138.52,43.25H99.68a6.38,6.38,0,0,1-6.38-6.38V22.76a6.38,6.38,0,0,1,6.38-6.38h38.84a6.37,6.37,0,0,1,6.38,6.38V36.87A6.38,6.38,0,0,1,138.52,43.25Z",
priority: 1
},
{
name: "A - Body",
pathDataName: "A-body-target",
pointValue: 5,
path: "M148.75,246.43H89.46a6.37,6.37,0,0,1-6.37-6.37V116.27a6.37,6.37,0,0,1,6.37-6.37h59.29a6.37,6.37,0,0,1,6.37,6.37V240.06A6.38,6.38,0,0,1,148.75,246.43Z",
priority: 1
},
{
name: "B",
pathDataName: "B-target",
pointValue: 4,
path: "M160.43,73.35H75.5V.25h84.93Z",
priority: 2
},
{
name: "C",
pathDataName: "C-target",
pointValue: 3,
path: "M68.74,300.71,43.79,242.87l1.35-138.19-.22-4.56L63.8,77.62l3.59-4.27h99.8L172.12,78,191,100.52l-.21,4.56,1.35,138.19-1.54,3.57-22.74,53.87H68.74Z",
priority: 2
},
{
name: "D",
pathDataName: "D-target",
pointValue: 2,
path: "M40,377.57.25,300.17,2.4,115.27l-.34-6.1,30.1-30.1,5.72-5.72H197l7.86,6.25,30.1,30.1-.34,6.11,2.15,184.9-2.45,4.78-36.25,72.08H40Z",
priority: 3
}
]
};
Expand All @@ -104,9 +92,8 @@ export let treePlate = {
scoringZones: [
{
name: "Plate Hit",
pathDataName: "plate",
pointValue: 1,
path: "M68.5,17.5v25H55.42a29,29,0,1,1,.48-25Z",
priority: 1
}
]
};
Expand All @@ -123,9 +110,8 @@ export let treePlateFlipped = {
scoringZones: [
{
name: "Plate Hit",
pathDataName: "plate-flipped",
pointValue: 1,
path: "M.5,41.5v-25H13.58a29,29,0,1,1-.48,25Z",
priority: 1
}
]
}
Expand All @@ -142,27 +128,23 @@ export let bullseye = {
scoringZones: [
{
name: "Bullseye",
pathDataName: "10-ring",
pointValue: 10,
path: "M175.5,125.5a50,50,0,1,1-50-50A50,50,0,0,1,175.5,125.5Z",
priority: 1
},
{
name: "8",
pathDataName: "8-ring",
pointValue: 8,
path: "M200.5,125.5a75,75,0,1,1-75-75A75,75,0,0,1,200.5,125.5Z",
priority: 2
},
{
name: "6",
pathDataName: "6-ring",
pointValue: 6,
path: "M225.5,125.5a100,100,0,1,1-100-100A100,100,0,0,1,225.5,125.5Z",
priority: 3
},
{
name: "4",
pathDataName: "4-ring",
pointValue: 4,
path: "M250.5,125.5A125,125,0,1,1,125.5.5,125,125,0,0,1,250.5,125.5Z",
priority: 4
}
]
}
Expand Down
Loading

0 comments on commit 9df2788

Please sign in to comment.