我正在绘制一个拱门,然后想从拱门的末端以给定的长度以直角绘制一条线。
我了解L和V命令,但对于L命令,我需要一个我没有的特定点,并且V命令与给定点不成直角。
还有其他命令可以帮助我吗?还是我应该尝试计算端点然后使用L命令?
如果是这样,您将如何计算?
提前谢谢!
编辑:
我的代码如下:
$arcpath = "<path d=\"M $circstartx $circstarty L $startx $starty A $radius $radius, 0, 0 $largeArcflag, $endx $endy L $circendx $circendy\" fill=\"none\" stroke=\"black\" />";
and generates a path like this
现在剩下的路径需要像 this
希望这可以更好地说明
编辑2:
我有一种方法可以正常工作,但是我有一个问题。
for ($i=0; $i<count($json_a->pie); $i++) {
//value in degrees
$valdeg = $json_a->pie[$i]->value1 / $valges * 360.0;
//startang is 0 in the first iteration
$endang = $startang + $valdeg;
//transform deg in rad of start and end angle
$valradstart = ($startang-90) * $M_PI /180.0;
$valradend = ($endang-90)* $M_PI /180.0;
if ($endang - $startang <= 180){
$largeArcflag = 0;
}else {
$largeArcflag = 1;
}
$valradstart2 = $valradstart + ($M_PI/6);
$valradend2 = $valradend - ($M_PI/6);
//calculate the start and end coordinates
$startx= $x + ($radius * cos($valradend));
$starty= $y + ($radius * sin($valradend));
$endx= $x + ($radius * cos($valradstart));
$endy= $y + ($radius * sin($valradstart));
//inner
$innerstartx= $x + ($innerradius * cos($valradend));
$innerstarty= $y + ($innerradius * sin($valradend));
$innerendx= $x + ($innerradius * cos($valradstart));
$innerendy= $y + ($innerradius * sin($valradstart));
//height depending on var in .json
//$circradius -= $pieheight;
//circle around the middle for the fold up
$circstartx= $x + ($circradius * cos($valradend));
$circstarty= $y + ($circradius * sin($valradend));
$circendx= $x + ($circradius * cos($valradstart));
$circendy= $y + ($circradius * sin($valradstart));
//circle around the middle for the fold up
$circstartx2= $x + ($circradius * cos($valradend2));
$circstarty2= $y + ($circradius * sin($valradend2));
$circendx2= $x + ($circradius * cos($valradstart2));
$circendy2= $y + ($circradius * sin($valradstart2));
$startx2= $x + ($radius * cos($valradend2));
$starty2= $y + ($radius * sin($valradend2));
$endx2= $x + ($radius * cos($valradstart2));
$endy2= $y + ($radius * sin($valradstart2));
$innerstartx2= $x + ($innerradius * cos($valradend2));
$innerstarty2= $y + ($innerradius * sin($valradend2));
$innerendx2= $x + ($innerradius * cos($valradstart2));
$innerendy2= $y + ($innerradius * sin($valradstart2));
//write into the svg file
$arcpath = "<path d=\"M $circstartx $circstarty L $startx $starty A $radius $radius, 0, 0 $largeArcflag, $endx $endy\" fill=\"none\" stroke=\"black\" />";
//$arcpath = "<path d=\"M $startx $starty A $radius $radius, 0, 0 $largeArcflag, $endx $endy L $circendx $circendy\" fill=\"none\" stroke=\"black\" />";
$lineconnect = "<path d=\"M $circendx $circendy L $circstartx2 $circstarty2 M $circendx2 $circendy2 L $circstartx $circstarty \" fill=\"none\" stroke=\"black\" stroke-dasharray=\"1, 1\" />";
$line2 = "<path d=\"M $circstartx2 $circstarty2 L $innerstartx2 $innerstarty2 M $innerendx2 $innerendy2 L $circendx2 $circendy2 \" fill=\"none\" stroke=\"black\" />";
$innerarcpath ="<path d=\"M $innerendx2 $innerendy2 A $innerradius $innerradius, 0, 0 $largeArcflag, $innerstartx2 $innerstarty2 \" fill=\"none\" stroke=\"black\" />";
$innerarcpath2 ="<path d=\"M $innerstartx $innerstarty A $innerradius $innerradius, 0, 0 $largeArcflag, $innerendx $innerendy \" fill=\"none\" stroke=\"black\" stroke-dasharray=\"1, 1\" />";
我现在只需要访问给定距离的中间和内部圆上的一个点。
例如在弧线上但沿弧线10px的点。
您可以通过任何方式访问这样的点吗?
$valradstart2 = $valradstart + ($M_PI/6);
$valradend2 = $valradend - ($M_PI/6);
我像这样尝试过,但是圆弧上的距离根据饼图的大小而有所不同。
我只需要一种方法来访问左右方向上的Arc X距离上的点。
谢谢!
答案 0 :(得分:0)
正如Paul LeBeau已经评论过的那样,您可能必须使用某些sin
和cos
函数才能获得所需的内容。特别是在圆弧和曲线方面,事情变得更加复杂。
但是,当您使用
时,存在一个简单的解决方案l
)如果您沿着l<a>,<b>
或l<n*b>,<-n*a>
沿着l<-n*b>,<n*a>
行,您将自动以直角进行绘制(n
可以是任意因素)。查看下面的小提琴。通过在交互式提示中输入任何值,您将生成不同角度但始终彼此垂直的线。
var [a,b]=prompt('please enter a,b:','40,70').split(',');
document.querySelector('svg').innerHTML='<path d="M20,20 l'
+( 2*a)+','+( 2*b)
+' '+(-.5*b)+','+( .5*a)
+' '+(-.5*a)+','+(-.5*b)
+' '+ b +','+( -a)
+'" stroke="#000" fill="none" >';
<svg width=400 height=400></svg>
答案 1 :(得分:0)
如果您要绘制扇形图,各段之间有一些固定的间隙,则可以执行以下操作:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="600">
<g style="stroke:black;stroke-width:1">
<?php
function pt($r,$ang,$mns=-1){ global $x,$y,$rad,$gap;
$a=($ang-90)*$rad-$mns*asin($gap/$r);
return sprintf('%0.2f,%0.2f',$x+$r*cos($a),$y+$r*sin($a));
}
// define global variables:
$json_a=new stdClass();
$json_a->pie=array(30,20,40,40,30,30); // pie chart values: as few or many as you like!
$r=50;$x=210;$y=210;$ri=100; $rc=200;
$a360=360/array_sum($json_a->pie); $M_PI=3.14159265358; $rad=$M_PI/180.;
$out='';$gap=4;$ang1=0; // start angle
foreach ($json_a->pie as $num) {
$dang = $num * $a360; // delta angle
$laf = $dang > 180? 1 : 0; // Large Arc Flag
$ang2 = $ang1 + $dang; // second angle
$out.= '<path d="M'.pt($rc,$ang1).'L'.pt($r, $ang1)."A $r,$r, 0,$laf,1 " .pt($r,$ang2,1).
'L'.pt($rc,$ang2,1)."A $rc,$rc, 0,$laf,0, ".pt($rc,$ang1).'" style="fill:hsl('.floor($ang1).',80%,55%)" />'."\n";
$ang1=$ang2;
}
echo "$out";
?></g></svg>
可以在http://rextester.com/HGGAH45381下找到php-demo。
这将产生以下结果:
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="800" height="600">
<g style="stroke:black;stroke-width:1">
<path d="M214.00,10.04L214.00,160.16A 50,50, 0,0,1 249.54,179.39L375.21,97.28A 200,200, 0,0,0, 214.00,10.04" style="fill:hsl(0,80%,55%)" />
<path d="M379.59,103.98L253.91,186.09A 50,50, 0,0,1 260.00,210.13L409.61,222.53A 200,200, 0,0,0, 379.59,103.98" style="fill:hsl(56,80%,55%)" />
<path d="M408.95,230.50L259.34,218.10A 50,50, 0,0,1 222.15,258.50L246.86,406.57A 200,200, 0,0,0, 408.95,230.50" style="fill:hsl(94,80%,55%)" />
<path d="M238.97,407.89L214.26,259.82A 50,50, 0,0,1 165.96,233.68L28.49,293.99A 200,200, 0,0,0, 238.97,407.89" style="fill:hsl(170,80%,55%)" />
<path d="M25.28,286.66L162.75,226.36A 50,50, 0,0,1 166.09,186.09L40.41,103.98A 200,200, 0,0,0, 25.28,286.66" style="fill:hsl(246,80%,55%)" />
<path d="M44.79,97.28L170.46,179.39A 50,50, 0,0,1 206.00,160.16L206.00,10.04A 200,200, 0,0,0, 44.79,97.28" style="fill:hsl(303,80%,55%)" />
</g></svg>
注意段之间的间隙。现在,该差距由$deltaAngle = asin($gap/$radius)
计算(=最近编辑!)。该计算已集成到功能pt()
中。基于弧长的原始计算(不使用asin()
)会产生较大间隙的误差。