目前正在构建基于浏览器的SVG应用程序.在这个应用程序中,用户可以设置和定位各种形状,包括矩形.
当我将一个stroke-widthSVG rect元素应用于某个SVG 元素时1px,rect不同浏览器会以不同的方式将笔划应用于偏移和插入.这被证明是麻烦的,特别是当我尝试计算矩形的外部宽度和视觉位置并将其放置在其他元素旁边时.
例如:
到目前为止,我唯一的解决方案是自己绘制实际边界(可能使用path工具)并将边框定位在描边元素后面.但是这个解决方案是一个令人不快的解决方案,如果可能的话,我宁愿不走这条路.
所以我的问题是,你能控制如何stroke-width在元素上绘制SVG 吗?
以下SVG路径可以绘制一个圆的99.99%:(在http://jsfiddle.net/DFhUF/46/上尝试它,看看你是否看到4个弧或只有2个,但请注意,如果它是IE,它会被渲染在VML中,而不是SVG,但有类似的问题)
M 100 100 a 50 50 0 1 0 0.00001 0
Run Code Online (Sandbox Code Playgroud)
但是当它是一个圆圈的99.99999999%时,什么都没有显示出来?
M 100 100 a 50 50 0 1 0 0.00000001 0
Run Code Online (Sandbox Code Playgroud)
这与100%的圆圈相同(它仍然是弧形,不是它,只是一个非常完整的圆弧)
M 100 100 a 50 50 0 1 0 0 0
Run Code Online (Sandbox Code Playgroud)
怎么能修好?原因是我使用一个函数绘制一个弧的百分比,如果我需要"特殊情况"一个99.9999%或100%的弧来使用圆函数,那就太傻了.
同样,使用RaphaelJS的jsfiddle上的测试用例位于http://jsfiddle.net/DFhUF/46/
(如果它是IE 8上的VML,即使第二个圆圈也不会显示......你必须将它改为0.01)
更新:
这是因为我在我们的系统中为得分渲染弧,所以3.3点得到1/3的圆.0.5得到半圈,9.9得到99%的圈.但是如果我们的系统中得分为9.99呢?我是否必须检查它是否接近圆的99.999%,并相应地使用arc函数或circle函数?那么得分9.9987怎么样?哪一个使用?要知道什么样的分数将映射到"太完整的圆圈"并切换到圆形函数是荒谬的,当它是圆圈的"某个99.9%"或9.9987分数时,则使用弧函数.
当绘制二维弧,用Bezier曲线近似,如何计算给定的,你有一个圆圈,开始和结束的角度和半径的中心点在两个控制点?
我试图用Python创建一个色轮,最好使用Matplotlib.以下工作正常:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
xval = np.arange(0, 2*pi, 0.01)
yval = np.ones_like(xval)
colormap = plt.get_cmap('hsv')
norm = mpl.colors.Normalize(0.0, 2*np.pi)
ax = plt.subplot(1, 1, 1, polar=True)
ax.scatter(xval, yval, c=xval, s=300, cmap=colormap, norm=norm, linewidths=0)
ax.set_yticks([])
Run Code Online (Sandbox Code Playgroud)
然而,这种尝试有两个严重的缺点.
首先,当将结果图形保存为矢量(figure_1.svg)时,色轮包含(如预期)621种不同的形状,对应于绘制的不同(x,y)值.虽然结果看起来像一个圆圈,但事实并非如此.我更倾向于使用一个实际的圆,由几个路径点和它们之间的贝塞尔曲线定义,如例如matplotlib.patches.Circle.这在我看来是"正确"的方式,结果看起来更好(没有条带,更好的渐变,更好的抗锯齿).
第二个(相关地),最终绘制的标记(前面的最后几个2*pi)与前几个重叠.在像素渲染中很难看到,但如果你放大基于矢量的渲染,你可以清楚地看到最后一张光盘与前几张光盘重叠.
我尝试使用不同的标记(.或|),但没有一个绕过第二个问题.
底线:我可以在Python/Matplotlib中绘制一个圆圈,它以适当的矢量/贝塞尔曲线方式定义,并且具有根据色彩图定义的边缘颜色(或者,失败,任意颜色渐变)?
我使用javascript和画布绘制数学设计的刻度(用于测量扭矩,它包括牛顿米和英尺 - 磅).我一直在使用三角函数定位我的刻度线arc,并自然地使用绘制弧形线.问题出现在他们需要排队的时候,但是有一些奇怪的失真.然后我绘制了一个非常大的圆圈并将其与GIMP中的圆形选择进行比较,并且存在失真.圆圈周围每45度一致,但在这些节点之间,画布绘制的圆圈向外偏离,就像八角形可以向外圆形太远以近似圆形.
为什么会出现这些扭曲?如何在画布上绘制一个真正的圆形圆圈?
这是我用来生成扭曲圆圈的代码.
<!DOCTYPE html>
<html>
<body>
<canvas width=8000 height=8000 id='myCanvas'></canvas>
<script>
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
context.beginPath();
context.arc(4000, 4000, 3200, 0, Math.PI*2, false);
context.lineWidth = 1;
context.strokeStyle = '#ff0000';
context.lineCap = 'square';
context.stroke();
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
这可能不是最小的,我不知道context.lineCap它的相关性,但它是基于此代码的遗迹.以下屏幕截图显示了GIMP绘制的圆与Chrome绘制的圆之间的区别

我有几点,我尝试使用下面的代码绘制贝塞尔曲线
PathFigure pf = new PathFigure(points.From, ps, false); //ps - list of Bezier segments
PathFigureCollection pfc = new PathFigureCollection();
pfc.Add(pf);
var pge = new PathGeometry();
pge.Figures = pfc;
Path p = new Path();
p.Data = pge;
p.Stroke = new SolidColorBrush(Color.FromRgb(244, 111, 011));
Run Code Online (Sandbox Code Playgroud)
我的Bezier部分看起来像这样
但我得到了这条奇怪的曲线(这里有3个大(节点)和7个小椭圆(是我的点)):

好的,这不是一个错误,但我对如何通过Bézier曲线在点之间获得完美的圆弧感到困惑.
我需要这样的形状:

所以我从中心点,半径和角度计算出这样的四个角点,用下面的公式计算:(x?,y?)=(x + dcosα,y + dsinα),这在我的coffeescript看起来像这样:
x1 = centerPointX+outerRadius*Math.cos(currentAngle)
y1 = centerPointY+outerRadius*Math.sin(currentAngle)
x2 = centerPointX+innerRadius*Math.cos(currentAngle)
y2 = centerPointY+innerRadius*Math.sin(currentAngle)
x3 = centerPointX+outerRadius*Math.cos(currentAngle2)
y3 = centerPointY+outerRadius*Math.sin(currentAngle2)
x4 = centerPointX+innerRadius*Math.cos(currentAngle2)
y4 = centerPointY+innerRadius*Math.sin(currentAngle2)
Run Code Online (Sandbox Code Playgroud)
如何获取我所拥有的信息并生成具有完美圆形曲线的路径元素?
(PS我对SVG很新,如果你想帮助我使用d =的正确语法,那将很酷,但我总是可以自己写.我想要帮助的挑战更多是与Bézier有关.
更新/解决方案
使用下面的答案,下面的指导是我实际使用的功能:
annularSector = (centerX,centerY,startAngle,endAngle,innerRadius,outerRadius) ->
startAngle = degreesToRadians startAngle+180
endAngle = degreesToRadians endAngle+180
p = [
[ centerX+innerRadius*Math.cos(startAngle), centerY+innerRadius*Math.sin(startAngle) ]
[ centerX+outerRadius*Math.cos(startAngle), centerY+outerRadius*Math.sin(startAngle) ]
[ centerX+outerRadius*Math.cos(endAngle), centerY+outerRadius*Math.sin(endAngle) ]
[ centerX+innerRadius*Math.cos(endAngle), centerY+innerRadius*Math.sin(endAngle) ]
]
angleDiff = endAngle - startAngle
largeArc = (if (angleDiff % (Math.PI * …Run Code Online (Sandbox Code Playgroud) 就像下面的图片所示,我有两个坐标,我想画一个椭圆,其长轴边缘与这两点相匹配。
我尝试获取这两个坐标之间的中点,并在这一个坐标上绘制一个椭圆形底。像这样的代码,下面的函数返回我想要的椭圆点数组:
function add_oval(centre, x, y) {
var assemble = new Array();
var angle;
var dot;
var tangent = x / y;
for (i = 0; i < 36; i++) {
angle = (2 * Math.PI / 36) * i;
dot = [centre.lng + Math.sin(angle) * y * tangent, centre.lat + Math.cos(angle) * y];
assemble.push(dot);
}
return assemble;
}
Run Code Online (Sandbox Code Playgroud)
但问题是,这些只能画水平椭圆,我不知道如何改变角度。
有人知道如何解决我的问题吗?
我正在尝试制作一个 Gauge UIView 来尽可能模仿以下图像

func gradientBezierPath(percent: CGFloat) -> UIBezierPath {
// vary this to move the start of the arc
let startAngle = CGFloat(180).toRadians()//-CGFloat.pi / 2 // This corresponds to 12 0'clock
// vary this to vary the size of the segment, in per cent
let proportion = CGFloat(50 * percent)
let centre = CGPoint (x: self.frame.size.width / 2, y: self.frame.size.height / 2)
let radius = self.frame.size.height/4//self.frame.size.width / (CGFloat(130).toRadians())
let arc = CGFloat.pi * 2 * proportion / 100 // …Run Code Online (Sandbox Code Playgroud)