Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Julian Frosch
BezLinApp
Commits
c0ac78d4
Commit
c0ac78d4
authored
Feb 08, 2016
by
Julian Frosch
Browse files
First working approximation; references Issue
#7
parent
d643d040
Changes
3
Hide whitespace changes
Inline
Side-by-side
js/approximation/approximator.js
View file @
c0ac78d4
...
...
@@ -9,7 +9,7 @@ function Approximator(paths, precision) {
/**
Returns the distance between two points in 2D-Space
*/
var
getDistance
=
function
(
x1
,
y1
,
x2
,
y2
)
{
method
.
getDistance
=
function
(
x1
,
y1
,
x2
,
y2
)
{
var
xd
=
x2
-
x1
;
var
yd
=
y2
-
y1
;
return
Math
.
sqrt
(
xd
*
xd
+
yd
*
yd
);
...
...
@@ -19,10 +19,11 @@ var getDistance = function(x1, y1, x2, y2) {
Returns the midpoint between two given points in 2D-Space.
Midpoint is returned as an Array: [x,y]
*/
var
getMidpoint
=
function
(
x1
,
y1
,
x2
,
y2
)
{
method
.
getMidpoint
=
function
(
x1
,
y1
,
x2
,
y2
)
{
var
ret
=
[];
ret
.
push
((
x1
+
x2
)
/
2
);
ret
.
push
((
y1
+
y2
)
/
2
);
return
ret
;
}
/**
...
...
@@ -30,9 +31,22 @@ var getMidpoint = function(x1, y1, x2, y2) {
Returns an array containing two arrays with the points for the curves:
[curve1, curve2] where each curve is [p0,p1,p2,p3] and each point is [x,y].
*/
var
approximateCurve
=
function
(
points
)
{
var
nPoints
=
[];
// TODO: implement
method
.
approximateCurve
=
function
(
p00
,
p01
,
p02
,
p03
)
{
// first layer midpoints
var
p10
=
this
.
getMidpoint
(
p00
[
0
],
p00
[
1
],
p01
[
0
],
p01
[
1
]);
var
p11
=
this
.
getMidpoint
(
p01
[
0
],
p01
[
1
],
p02
[
0
],
p02
[
1
]);
var
p12
=
this
.
getMidpoint
(
p02
[
0
],
p02
[
1
],
p03
[
0
],
p03
[
1
]);
// second layer midpoints
var
p20
=
this
.
getMidpoint
(
p10
[
0
],
p10
[
1
],
p11
[
0
],
p11
[
1
]);
var
p21
=
this
.
getMidpoint
(
p11
[
0
],
p11
[
1
],
p12
[
0
],
p12
[
1
]);
// third layer midpoint
var
p30
=
this
.
getMidpoint
(
p20
[
0
],
p20
[
1
],
p21
[
0
],
p21
[
1
]);
var
c1
=
[
p00
,
p10
,
p20
,
p30
];
var
c2
=
[
p30
,
p21
,
p12
,
p03
];
return
[
c1
,
c2
];
}
/**
...
...
@@ -41,18 +55,22 @@ var approximateCurve = function(points) {
If it is reached, a "LineTo"-command will be created, else another curve-command.
Both are absolute; this method does not create relative commands.
*/
var
buildCurveCommands
=
function
(
curves
)
{
method
.
buildCurveCommands
=
function
(
curves
)
{
var
commands
=
[];
curves
.
forEach
(
function
(
curve
)
{
if
(
getDistance
(
curve
[
0
][
0
],
curve
[
0
][
1
],
curve
[
3
][
0
],
curve
[
3
][
1
])
<=
this
.
_precision
.
getPrecision
(
curve
[
0
][
0
],
curve
[
0
][
1
]))
{
for
(
var
i
=
0
;
i
<
curves
.
length
;
i
++
)
{
var
curve
=
curves
[
i
];
var
d
=
this
.
getDistance
(
curve
[
0
][
0
],
curve
[
0
][
1
],
curve
[
3
][
0
],
curve
[
3
][
1
]);
var
p
=
this
.
_precision
.
getPrecision
(
curve
[
0
][
0
],
curve
[
0
][
1
]);
if
(
d
<=
p
)
{
// transform into "L"-command from p0 -> p3
commands
.
push
([
"
L
"
,
curve
[
0
][
0
],
curve
[
0
][
1
],
curve
[
3
][
0
],
curve
[
3
][
1
]]);
}
else
{
// build "C"-command and push it
commands
.
push
([
"
C
"
,
curve
[
0
][
0
],
curve
[
0
][
1
],
curve
[
1
][
0
],
curve
[
1
][
1
],
curve
[
2
][
0
],
curve
[
2
][
1
],
curve
[
3
][
0
],
curve
[
3
][
1
]]);
}
}
)
}
return
commands
;
}
...
...
@@ -60,71 +78,96 @@ var buildCurveCommands = function(curves) {
/**
This method approximates one specific path and returns the approximation as a new SVG-Path.
*/
var
approximatePath
=
function
(
pathNo
)
{
// TODO: Maybe change this to only work with the "available" data instead of "copying"
//var path = this._paths[pathNo];
method
.
approximatePath
=
function
(
pathNo
)
{
var
path
=
this
.
_paths
[
pathNo
];
var
nPath
=
[];
var
sPoint
=
[];
var
curveFound
=
fals
e
;
var
sPoint
=
[
0
,
0
];
var
curveFound
=
tru
e
;
// TODO: Whole thing is not really DRY... maybe find a better solution?
for
(
var
i
=
0
;
i
<
this
.
_paths
[
pathNo
].
length
;
i
++
)
{
// get every command, approximate curves
var
cmd
=
this
.
_paths
[
pathNo
][
i
];
switch
(
cmd
[
0
])
{
case
"
m
"
:
// adjust sPoint to values (relative)
sPoint
[
0
]
+=
cmd
[
1
];
sPoint
[
1
]
+=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
case
"
M
"
:
// adjust sPoint to values (absolute)
sPoint
[
0
]
=
cmd
[
1
];
sPoint
[
1
]
=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
case
"
c
"
:
// approximate one cycle (relative)
curveFound
=
true
;
var
p1
=
[
sPoint
[
0
]
+
cmd
[
1
],
sPoint
[
1
]
+
cmd
[
2
]];
var
p2
=
[
p1
[
0
]
+
cmd
[
3
],
p1
[
1
]
+
cmd
[
4
]];
var
p3
=
[
p2
[
0
]
+
cmd
[
5
],
p2
[
1
]
+
cmd
[
6
]];
var
ret
=
buildCurveCommands
(
approximatePath
(
sPoint
,
p1
,
p2
,
p3
));
// TODO: Test this
ret
.
forEach
(
function
(
command
)
{
nPath
.
push
(
command
);
});
// TODO: set new sPoint!
break
;
case
"
C
"
:
// approximate one cycle (absolute)
curveFound
=
true
;
var
p1
=
[
cmd
[
1
],
cmd
[
2
]];
var
p2
=
[
cmd
[
3
],
cmd
[
4
]];
var
p3
=
[
cmd
[
5
],
cmd
[
6
]];
var
ret
=
buildCurveCommands
(
approximatePath
(
sPoint
,
p1
,
p2
,
p3
));
// TODO: Test this
ret
.
forEach
(
function
(
command
)
{
nPath
.
push
(
command
);
});
break
;
case
"
l
"
:
// copy values, set sPoint (relative)
sPoint
[
0
]
+=
cmd
[
1
];
sPoint
[
1
]
+=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
case
"
L
"
:
// copy values, set sPoint (absolute)
sPoint
[
0
]
=
cmd
[
1
];
sPoint
[
1
]
=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
default
:
// TODO: implement default/failure-behaviour
while
(
curveFound
)
{
curveFound
=
false
;
for
(
var
i
=
0
;
i
<
path
.
length
;
i
++
)
{
// get every command, approximate curves
var
cmd
=
path
[
i
];
switch
(
cmd
[
0
])
{
case
"
m
"
:
// adjust sPoint to values (relative)
sPoint
[
0
]
+=
cmd
[
1
];
sPoint
[
1
]
+=
cmd
[
2
];
// then push it as an absolute command
nPath
.
push
([
"
M
"
,
sPoint
[
0
],
sPoint
[
1
]]);
break
;
case
"
M
"
:
// adjust sPoint to values (absolute)
sPoint
[
0
]
=
cmd
[
1
];
sPoint
[
1
]
=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
case
"
c
"
:
// approximate one cycle (relative)
curveFound
=
true
;
var
p1
=
[
sPoint
[
0
]
+
cmd
[
1
],
sPoint
[
1
]
+
cmd
[
2
]];
var
p2
=
[
p1
[
0
]
+
cmd
[
3
],
p1
[
1
]
+
cmd
[
4
]];
var
p3
=
[
p2
[
0
]
+
cmd
[
5
],
p2
[
1
]
+
cmd
[
6
]];
var
curves
=
this
.
approximateCurve
(
sPoint
,
p1
,
p2
,
p3
);
// set new startingpoint to last point of second curve
sPoint
[
0
]
=
curves
[
1
][
3
][
0
];
sPoint
[
1
]
=
curves
[
1
][
3
][
1
];
// build commands
var
commands
=
this
.
buildCurveCommands
(
curves
);
// TODO: Test this
// add commands to "new" path
commands
.
forEach
(
function
(
command
)
{
nPath
.
push
(
command
);
});
break
;
case
"
C
"
:
// approximate one cycle (absolute)
curveFound
=
true
;
var
p1
=
[
cmd
[
1
],
cmd
[
2
]];
var
p2
=
[
cmd
[
3
],
cmd
[
4
]];
var
p3
=
[
cmd
[
5
],
cmd
[
6
]];
var
curves
=
this
.
approximateCurve
(
sPoint
,
p1
,
p2
,
p3
);
// set new startingpoint to last point of second curve
sPoint
[
0
]
=
curves
[
1
][
3
][
0
];
sPoint
[
1
]
=
curves
[
1
][
3
][
1
];
// build commands
var
commands
=
this
.
buildCurveCommands
(
curves
);
// TODO: Test this
// add commands to "new" path
commands
.
forEach
(
function
(
command
)
{
nPath
.
push
(
command
);
});
break
;
case
"
l
"
:
// copy values, set sPoint (relative)
sPoint
[
0
]
+=
cmd
[
1
];
sPoint
[
1
]
+=
cmd
[
2
];
// push it as an absolute command
nPath
.
push
([
"
L
"
,
sPoint
[
0
],
sPoint
[
1
]]);
break
;
case
"
L
"
:
// copy values, set sPoint (absolute)
sPoint
[
0
]
=
cmd
[
1
];
sPoint
[
1
]
=
cmd
[
2
];
nPath
.
push
(
cmd
);
break
;
case
"
Z
"
:
// just copy z-commands
nPath
.
push
(
cmd
);
default
:
// TODO: implement default/failure-behaviour
// ignore other commands, maybe warn user about it!
}
}
// "reset" values for a new cycle
path
=
nPath
;
nPath
=
[];
sPoint
=
[
0
,
0
];
}
// when this point of code is reached, all curves in this path have been replaced by lines.
return
path
;
}
/**
...
...
@@ -132,7 +175,7 @@ var approximatePath = function(pathNo) {
*/
method
.
approximateData
=
function
(
callback
)
{
for
(
var
i
=
0
;
i
<
this
.
_paths
.
length
;
i
++
)
{
var
retPath
=
approximatePath
(
i
);
var
retPath
=
this
.
approximatePath
(
i
);
this
.
_paths
[
i
]
=
retPath
;
}
callback
(
null
,
this
.
_paths
);
...
...
js/approximation/precisionMap.js
View file @
c0ac78d4
...
...
@@ -2,26 +2,32 @@ var method = PrecisionMap.prototype;
// constructor
function
PrecisionMap
(
data
,
min
,
max
)
{
this
.
_data
=
data
;
if
((
typeof
data
)
==
'
object
'
)
{
this
.
_data
=
data
;
/*
FYI - NDArray Format: ((x),(y),(r,g,b,a))
Access pixel with ....get(x,y,c)
e.g.:
console.log("Red", pixels.get(0,0,0), pixels.get(0,0,1), pixels.get(0,0,2), pixels.get(0,0,3));
console.log("Blue", pixels.get(1,0,0), pixels.get(1,0,1), pixels.get(1,0,2), pixels.get(1,0,3));
console.log("Black", pixels.get(2,0,0), pixels.get(2,0,1), pixels.get(2,0,2), pixels.get(2,0,3));
*/
/*
FYI - NDArray Format: ((x),(y),(r,g,b,a))
Access pixel with ....get(x,y,c)
e.g.:
console.log("Red", pixels.get(0,0,0), pixels.get(0,0,1), pixels.get(0,0,2), pixels.get(0,0,3));
console.log("Blue", pixels.get(1,0,0), pixels.get(1,0,1), pixels.get(1,0,2), pixels.get(1,0,3));
console.log("Black", pixels.get(2,0,0), pixels.get(2,0,1), pixels.get(2,0,2), pixels.get(2,0,3));
*/
// get the dimensions
var
shape
=
this
.
_data
.
shape
.
slice
();
this
.
_w
=
shape
[
0
];
this
.
_h
=
shape
[
1
];
this
.
_c
=
shape
[
2
];
// get the dimensions
var
shape
=
this
.
_data
.
shape
.
slice
();
this
.
_w
=
shape
[
0
];
this
.
_h
=
shape
[
1
];
this
.
_c
=
shape
[
2
];
this
.
_min
=
min
;
this
.
_max
=
max
;
this
.
_diff
=
max
-
min
;
this
.
_min
=
min
;
this
.
_max
=
max
;
this
.
_diff
=
max
-
min
;
}
else
{
// no heatmap provided, we only have the "max"-value
this
.
_data
=
null
;
this
.
_max
=
data
;
}
}
/**
...
...
@@ -29,6 +35,9 @@ function PrecisionMap(data, min, max) {
x and y are floored in the method.
*/
method
.
getPrecision
=
function
(
x
,
y
)
{
if
(
this
.
_data
==
null
)
{
return
this
.
_max
;
}
var
value
=
this
.
_data
.
get
(
Math
.
floor
(
x
),
Math
.
floor
(
y
),
0
);
var
p
=
this
.
_max
+
this
.
_diff
*
(
x
/
255
);
return
p
;
...
...
js/script.js
View file @
c0ac78d4
...
...
@@ -50,6 +50,8 @@ $(function(){
console
.
log
(
"
Data fetched, printing:
"
);
console
.
dir
(
result
);
var
PrecisionMap
=
require
(
'
./js/approximation/precisionMap.js
'
);
if
(
heatmap
!=
null
)
{
// the user has provided a heatmap, so we need to consider the precision-values from it:
// first, parse the file:
...
...
@@ -65,7 +67,6 @@ $(function(){
console
.
log
(
pMax
);
var
pMin
=
document
.
getElementById
(
'
pMin
'
).
value
;
var
PrecisionMap
=
require
(
'
./js/approximation/precisionMap.js
'
);
var
map
=
new
PrecisionMap
(
pixels
,
pMin
,
pMax
);
console
.
log
(
map
.
getPrecision
(
0
,
0
));
...
...
@@ -74,13 +75,19 @@ $(function(){
var
approximator
=
new
Approximator
(
result
,
map
);
approximator
.
approximateData
(
function
(
err
,
nPaths
)
{
// do something more :)
console
.
dir
(
nPaths
);
});
});
}
else
{
// the user did not provide a heatmap, so just start the approximator
var
approximator
=
new
Approximator
(
result
,
null
);
// get the pMax-value, this will be the precision for all positions
var
pMax
=
document
.
getElementById
(
'
pMax
'
).
value
;
var
map
=
new
PrecisionMap
(
pMax
);
var
approximator
=
new
Approximator
(
result
,
map
);
approximator
.
approximateData
(
function
(
err
,
nPaths
)
{
// do something more :)
console
.
dir
(
nPaths
);
});
}
}
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment