fix arc command
This commit is contained in:
parent
56543b352e
commit
d22e2103b1
@ -11,12 +11,16 @@
|
||||
<body>
|
||||
|
||||
|
||||
<svg id="svg" style="opacity:0.5; position: absolute" width="1024px" height="1024px" viewBox="0 0 1024 1024">
|
||||
<svg id="svg" style="opacity:0.3; position: absolute" width="1024px" height="1024px" viewBox="0 0 1024 1024">
|
||||
<path id="path" fill="#000" d=""/>
|
||||
</svg>
|
||||
|
||||
<svg id="svg" style="opacity:0.3; position: absolute" width="1024px" height="1024px" viewBox="0 0 1024 1024">
|
||||
<path id="path1" fill="red" d=""/>
|
||||
</svg>
|
||||
|
||||
<svg width="1024px" height="1024px" viewBox="0 0 1024 1024">
|
||||
<path fill="yellow" d="M300,200 A150,100 0 1,1 300,300 z"/>
|
||||
<path fill="yellow" d="M300,200 A150,100 0 1,0 300,400 z"/>
|
||||
</svg>
|
||||
|
||||
|
||||
|
@ -20,9 +20,9 @@ define(
|
||||
init: function () {
|
||||
|
||||
// 300,200 A150,50 0 1,0 450,50
|
||||
var path = getArc(150, 100, 0, 1, 1, {x: 300, y:200}, {x:300, y:300});
|
||||
|
||||
var path = getArc(150, 100, 0, 1, 0, {x: 300, y:200}, {x:300, y:400});
|
||||
|
||||
console.log(path[0]);
|
||||
$('#path').attr('d', contour2svg(path));
|
||||
}
|
||||
};
|
||||
|
@ -4,6 +4,9 @@
|
||||
* @date
|
||||
* @description
|
||||
* 获取椭圆弧度
|
||||
*
|
||||
* references:
|
||||
* http://www.w3.org/TR/SVG/implnote.html#ArcImplementationNotes
|
||||
*/
|
||||
|
||||
define(
|
||||
@ -15,19 +18,18 @@ define(
|
||||
var pathAdjust = require('./pathAdjust');
|
||||
var pathRotate = require('./pathRotate');
|
||||
var quadraticEquation = require('math/quadraticEquation');
|
||||
var lang = require('common/lang');
|
||||
var isPathCross = require('./isPathCross');
|
||||
var interpolate = require('./join/interpolate');
|
||||
var deInterpolate = require('./join/deInterpolate');
|
||||
var getJoint = require('./join/getJoint');
|
||||
var pathSplit = require('./join/pathSplit');
|
||||
var lang = require('common/lang');
|
||||
|
||||
|
||||
// 圆路径
|
||||
var PATH_CIRCLE = [
|
||||
{"x":383,"y":0},{"x":207,"y":75},{"x":75,"y":208},{"x":0,"y":384},{"x":0,"y":583},{"x":75,"y":760},
|
||||
{"x":207,"y":891},{"x":383,"y":966},{"x":582,"y":966},{"x":758,"y":891},{"x":890,"y":760},
|
||||
{"x":965,"y":583},{"x":965,"y":384},{"x":890,"y":208},{"x":758,"y":75},{"x":582,"y":0}
|
||||
// 圆路径,逆时针
|
||||
var PATH_CIRCLE =[
|
||||
{"x":582,"y":0},{"x":758,"y":75},{"x":890,"y":208},{"x":965,"y":384},{"x":965,"y":583},{"x":890,"y":760},
|
||||
{"x":758,"y":891},{"x":582,"y":966},{"x":383,"y":966},{"x":207,"y":891},{"x":75,"y":760},{"x":0,"y":583},
|
||||
{"x":0,"y":384},{"x":75,"y":208},{"x":207,"y":75},{"x":383,"y":0}
|
||||
];
|
||||
|
||||
/**
|
||||
@ -65,9 +67,13 @@ define(
|
||||
*/
|
||||
function getArc(rx, ry, angle, largeArc, sweep, p0, p1) {
|
||||
|
||||
if (rx === 0 || ry === 0) {
|
||||
return [p0, p1];
|
||||
}
|
||||
|
||||
// Compute the center
|
||||
// see librsvg
|
||||
var f = angle * Math.PI / 180.0;
|
||||
var f = (angle % 360) * Math.PI / 180.0;
|
||||
var sinf = Math.sin(f);
|
||||
var cosf = Math.cos(f);
|
||||
|
||||
@ -87,9 +93,16 @@ define(
|
||||
var x1_ = cosf * k1 + sinf * k2;
|
||||
var y1_ = -sinf * k1 + cosf * k2;
|
||||
|
||||
// scale rx, ry
|
||||
var ita = Math.sqrt(Math.pow(x1_ / rx, 2)+ Math.pow(y1_ / ry, 2));
|
||||
if (ita > 1) {
|
||||
rx = ita * rx;
|
||||
ry = ita * ry;
|
||||
}
|
||||
|
||||
|
||||
k1 = rx * rx * y1_ * y1_ + ry * ry * x1_ * x1_;
|
||||
if(k1 == 0) {
|
||||
if(k1 === 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
@ -106,39 +119,57 @@ define(
|
||||
var cy = sinf * cx_ + cosf * cy_ + (y1 + y2) / 2;
|
||||
|
||||
|
||||
var ovalPath = interpolate(getOval(2 * rx, 2 * ry, f, {x: cx, y: cy}));
|
||||
|
||||
var p0_ = {x: x1, y: y1};
|
||||
var p1_ = {x: x2, y: y2};
|
||||
|
||||
// 将线段放大,防止无交点
|
||||
cx = (p0.x + p1.x) / 2;
|
||||
cy = (p0.y + p1.y) / 2;
|
||||
pathAdjust([p0, p1], 1.1, 1.1, -cx, -cy);
|
||||
pathAdjust([p0, p1], 1, 1, cx, cy);
|
||||
cx = (p0_.x + p1_.x) / 2;
|
||||
cy = (p0_.y + p1_.y) / 2;
|
||||
pathAdjust([p0_, p1_], 1.1, 1.1, -cx, -cy);
|
||||
pathAdjust([p0_, p1_], 1, 1, cx, cy);
|
||||
|
||||
var result = getJoint(ovalPath, 'L', p0, p1, 0, 0);
|
||||
// 这里弧度有负向的情况,需要转换成正向
|
||||
var ovalPath = interpolate(getOval(2 * rx, 2 * ry, f > 0 ? f : (f + Math.PI), {x: cx, y: cy}));
|
||||
var result = getJoint(ovalPath, 'L', p0_, p1_, 0, 0);
|
||||
|
||||
// 这里没有支持实际弦长比较大,需要缩放椭圆的情况,
|
||||
// 不会算。。囧
|
||||
// TODO
|
||||
// 这里必定会有交点,如果没有,则说明计算错误
|
||||
if (result) {
|
||||
ovalPath = pathSplit(ovalPath, result.map(function(p) {
|
||||
var ovalPaths = pathSplit(ovalPath, result.map(function(p) {
|
||||
p.index = p.index1;
|
||||
return p;
|
||||
})).sort(function(a, b) {
|
||||
return a.length - b.length;
|
||||
});
|
||||
}));
|
||||
|
||||
ovalPath = largeArc ? ovalPath[1] : ovalPath[0];
|
||||
// 弧线相等的时候需要判断 sweepflag
|
||||
var clockwise = y1 > y2 ? 1 : y1 < y2 ? -1 : (x1 > x2 ? 1 : -1);
|
||||
if (Math.abs(cx - (x1 + x2) / 2) < 0.01 && Math.abs(cy - (y1 + y2) / 2) < 0.01) {
|
||||
// 这里需要区分相交线段是否是逆时针
|
||||
if (sweep && clockwise == 1 || sweep == 0 && clockwise == -1) {
|
||||
ovalPath = ovalPaths[0];
|
||||
}
|
||||
else {
|
||||
ovalPath = ovalPaths[1];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (largeArc && ovalPaths[1].length > ovalPaths[0].length) {
|
||||
ovalPath = ovalPaths[1];
|
||||
}
|
||||
else {
|
||||
ovalPath = ovalPaths[0];
|
||||
}
|
||||
}
|
||||
|
||||
ovalPath = deInterpolate(ovalPath);
|
||||
// 逆向起始点
|
||||
var end = ovalPath[ovalPath.length - 1];
|
||||
|
||||
// 翻转
|
||||
if (Math.abs(p0.x - end.x) < 0.01 && Math.abs(p0.y - end.y) < 0.01) {
|
||||
ovalPath = ovalPath.reverse();
|
||||
}
|
||||
|
||||
return deInterpolate(ovalPath);
|
||||
return ovalPath;
|
||||
}
|
||||
else {
|
||||
console.warn('arc convert error!');
|
||||
return [p0, p1];
|
||||
}
|
||||
}
|
||||
|
@ -13,10 +13,6 @@ define(
|
||||
var isInsidePath = require('./isInsidePath');
|
||||
var isBoundingBoxCross = require('./isBoundingBoxCross');
|
||||
|
||||
function hashcode(p) {
|
||||
return p.x / 7 + p.y / 13 + (p.x + p.y) / 17;
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断x轴射线是否穿过线段
|
||||
*
|
||||
@ -46,23 +42,6 @@ define(
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
// 对结果集合进行筛选,去除重复点
|
||||
var hash = {};
|
||||
for (var i = result.length - 1; i >= 0; i--) {
|
||||
var p = result[i];
|
||||
if (hash[hashcode(p)]) {
|
||||
result.splice(i, 1);
|
||||
}
|
||||
else {
|
||||
hash[hashcode(p)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (result.length === 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,10 @@ define(
|
||||
var isBezierSegmentCross = require('../isBezierSegmentCross');
|
||||
var pathIterator = require('../pathIterator');
|
||||
|
||||
function hashcode(p) {
|
||||
return p.x / 7 + p.y / 13 + (p.x + p.y) / 17;
|
||||
}
|
||||
|
||||
/**
|
||||
* 求路径和曲线段的交点集合
|
||||
* @param {Array} path 路径
|
||||
@ -58,7 +62,23 @@ define(
|
||||
}
|
||||
});
|
||||
|
||||
return joint.length ? joint : false;
|
||||
// 对结果集合进行筛选,去除重复点
|
||||
var hash = {};
|
||||
for (var i = joint.length - 1; i >= 0; i--) {
|
||||
var p = joint[i];
|
||||
if (hash[hashcode(p)]) {
|
||||
joint.splice(i, 1);
|
||||
}
|
||||
else {
|
||||
hash[hashcode(p)] = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (joint.length <= 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return joint;
|
||||
}
|
||||
|
||||
return getJoint;
|
||||
|
Loading…
x
Reference in New Issue
Block a user