modify split params

This commit is contained in:
kekee000
2015-03-24 00:51:45 +08:00
parent 368420612f
commit dcb40f3087
6 changed files with 170 additions and 48 deletions

View File

@@ -23,29 +23,80 @@ define(
var THETA_TANGENCY = 0.1; // 相切抑制
var THETA_CORNER = 0.5; // 拐点抑制
var THETA_MARK_COUNT = 0.8; // 标记点个数抑制
var THETA_INFLEXION_RANGE = 0.05; // 切线点之间的距离抑制
function isLine(p0, p1, p) {
return 1 - Math.abs(getCos(p.x - p0.x, p.y - p0.y, p.x - p1.x, p.y - p1.y)) < 0.005;
return 1 - Math.abs(getCos(p.x - p0.x, p.y - p0.y, p.x - p1.x, p.y - p1.y)) < 0.001;
}
function removeOnLinePoint(contour) {
function removeOnLinePoint(points) {
// 移除直线上误判的点
for (var i = contour.length - 1, last = i; i >= 0; i--) {
for (var i = points.length - 1, last = i; i >= 0; i--) {
// 这里注意逆序
var p = contour[i];
var next = i === last ? contour[0] : contour[i + 1];
var prev = i === 0 ? contour[last] : contour[i - 1];
var p = points[i];
var next = i === last ? points[0] : points[i + 1];
var prev = i === 0 ? points[last] : points[i - 1];
if (isLine(prev, next, p)) {
contour.splice(i, 1);
points.splice(i, 1);
last--;
continue;
}
}
return contour;
return points;
}
function removeInflexionPoint(points, contour) {
// 移除过多的切线点
var contourSize = contour.length;
var range;
for (var i = points.length - 1, last = i; i >= 0; i--) {
// 这里注意逆序
var p = points[i];
var next = i === last ? points[0] : points[i + 1];
var prev = i === 0 ? points[last] : points[i - 1];
// 两个同为切线点
if (p.inflexion && next.inflexion) {
range = i === last ? last + 1 - p.index + next.index : next.index - p.index;
if (range / contourSize < THETA_INFLEXION_RANGE) {
if (p.absTheta > next.absTheta) {
points.splice(i, 1);
}
else {
points.splice(i + 1, 1);
}
last--;
continue;
}
}
// 拐点附近的切线点
else if (p.breakPoint && next.inflexion) {
range = i === last ? last + 1 - p.index + next.index : next.index - p.index;
if (range / contourSize < THETA_INFLEXION_RANGE) {
points.splice(i + 1, 1);
i--;
last--;
continue;
}
}
// 拐点附近的切线点
else if (p.inflexion && next.breakPoint) {
range = i === last ? last + 1 - p.index + next.index : next.index - p.index;
if (range / contourSize < THETA_INFLEXION_RANGE) {
points.splice(i, 1);
i--;
last--;
continue;
}
}
}
return points;
}
/**
* 对轮廓中的关键点做进一步提取
*
@@ -57,43 +108,60 @@ define(
var contourSize = contour.length;
breakPoints = removeOnLinePoint(breakPoints);
breakPoints = removeInflexionPoint(breakPoints, contour);
for (var i = 0, l = breakPoints.length; i < l; i++) {
var isLast = i === l - 1;
var start = breakPoints[i];
var end = breakPoints[ isLast ? 0 : i + 1];
// 中间点小于3个,则判断为直线
var count = isLast ? l - end.index : end.index - start.index;
if (start.breakPoint && end.breakPoint && count < 10) {
// 中间点小于10个,则判断为直线
var range = isLast ? l - start.index + end.index : end.index - start.index;
if (start.breakPoint && end.breakPoint && range < 10) {
start.right = 1;
end.left = 1;
}
else {
// 判断中间点距离
mid = contour[Math.floor((end.index + (isLast ? contourSize : start.index)) / 2)];
if (isLast) {
mid = contour[Math.floor(start.index + (contourSize - start.index + end.index) / 2) % contourSize];
}
else {
mid = contour[Math.floor((start.index + end.index) / 2)];
}
if (start.x === 3690 && start.y === 4250) {
debugger;
}
// 夹角接近直线
if (isLine(start, end, mid)) {
console.log(start);
// 随机选取 几个点进行直线判断
var startIndex = start.index + 10;
var endIndex = end.index - 1;
var startIndex = start.index;
var endIndex = end.index;
if (isLast) {
startIndex = end.index + 10;
endIndex = l + startIndex.index;
startIndex = start.index;
endIndex = contourSize + end.index;
}
var step = Math.floor(Math.max((endIndex - startIndex) / 10, 4));
var lineFlag = true;
for (var j = startIndex; j < endIndex; j+= 10) {
for (var j = startIndex + step; j < endIndex; j += step) {
if (!isLine(start, end, contour[j % contourSize])) {
lineFlag = false;
break;
}
}
if (lineFlag) {
start.right = 1;
end.left = 1;
}
else {
start.right = 2;
end.left = 2;
}
}
// 标记待选曲线
else {
@@ -103,8 +171,6 @@ define(
}
}
// 移除过多的切线点
return breakPoints;
}

View File

@@ -18,12 +18,12 @@ define(
*
* @return {Array} 结果点集
*/
function fitBezier(points, scale) {
function fitBezier(points, scale, tHat1) {
scale = scale || 1;
var size = points.length;
var maxError = 200;
var maxError = 10 * scale;
var cubicBezier = fitCurve(points, maxError);
var cubicBezier = fitCurve(points, maxError, tHat1);
var start = points[0];
var result = [];
for (var i = 0, l = cubicBezier.length; i < l; i += 3) {

View File

@@ -519,15 +519,20 @@ define(
*
* @return {Array} 结果点集
*/
function fitCurve(points, error) {
function fitCurve(points, error, tHat1, tHat2) {
var last = points.length - 1;
var tHat1 = computeLeftTangent(points, 0);
var tHat2 = computeRightTangent(points, last);
if (!tHat1) {
var tHat1 = computeLeftTangent(points, 0);
}
if (!tHat2) {
var tHat2 = computeRightTangent(points, last);
}
var result = [];
fitCubic(points, 0, last, tHat1, tHat2, error, result);
return result;
}
fitCurve.normalize = normalize;
return fitCurve;
}

View File

@@ -84,10 +84,24 @@ define(
}
/**
* 将点转换成余弦值
*
* @param {Object} p 点
* @return {Object} 余弦值
*/
function normalize(p) {
var factor = 1 / Math.sqrt(p.x * p.x + p.y * p.y);
p.x = p.x * factor;
p.y = p.y * factor;
return p;
}
return {
getCos: getCos,
getDist: getDist,
getDistPow: getDistPow
getDistPow: getDistPow,
normalize: normalize
};
}
);