Draw an eliptical line on a coordinate system based on focla points?

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-24 08:13:47

问题


I'm trying to draw a dashed line on a google map, so I can't use eshape.js. I need to create an array of points that approximate an elipse in a coordinate system. It's just for display so it doesn't have to be that precise.

If someone can just explain the math that's fine. Extra credit if you apply it in javascript ;)


回答1:


This is now something you can do within the Google Maps API. Recently, Google added Symbols to Polylines, allowing you to use SVG to style your lines: https://developers.google.com/maps/documentation/javascript/overlays#Symbols




回答2:


Give this a try (create a 1x1 bmp called blackpixel.bmp and add it next to the htm file you will create to contain the following code, should help you get waht you need. I found it here:

<HTML>
<HEAD>
<TITLE>
Ellipse example drawn to the screen, using a one-pixel black .bmp
image, for jackshu-ga
</TITLE>
<script type="text/javascript">

function draw()
{
coords=ellipseMaker(dataIn.foci1Top.value,dataIn.foci1Left.value,dataIn.foci2Top.value,dataIn.foci2Left.value,dataIn.semiMinor.value)

for(i=0;i<coords.length;i++)
   {
   document.write("<img src='blackpixel.bmp' id='pixel"+i+"' style='container: positioned; position: absolute; top: 50; left: 800'>")
   }

for(j=1;j<coords.length;j++)
   {
   document.images[j].style.top=coords[j][0]
   document.images[j].style.left=coords[j][1]
   }
}

function ellipseMaker(foci1Top, foci1Left, foci2Top, foci2Left,
semiMinor, jumpBy, streamline, increaseUnit, dontPopOutLast){
/* Requires gen 4 browsers: using concat(), shift(), pop()
* My thanks to G.E. Ivey from the sci/sci.math newsgroup 
* who helped with the (for me) complex ellipse translation/rotation
formula.
*/
//validate:
semiMinor=(semiMinor && !isNaN(parseFloat(semiMinor)) &&
parseFloat(semiMinor)>0)?
parseFloat(semiMinor):0.5;
foci1Top=(foci1Top && !isNaN(parseFloat(foci1Top)))?
parseFloat(foci1Top):0;
foci1Left=(foci1Left && !isNaN(parseFloat(foci1Left)))?
parseFloat(foci1Left):0;
foci2Top=(foci2Top && !isNaN(parseFloat(foci2Top)))?
parseFloat(foci2Top):0;
foci2Left=(foci2Left && !isNaN(parseFloat(foci2Left)))?
parseFloat(foci2Left):0;
increaseUnit=(increaseUnit && !isNaN(parseFloat(increaseUnit)))?
Math.abs( parseFloat(increaseUnit) ):0.5;
jumpBy=(jumpBy && !isNaN(parseFloat(jumpBy)))? parseFloat(jumpBy):0;
streamline= (streamline+""=="0")?0:1;
//initialize:
var major=Math.round( (Math.sqrt(
Math.pow(
(Math.max(foci1Top, foci2Top)-Math.min(foci1Top, foci2Top))
,2)+
Math.pow(
(Math.max(foci1Left, foci2Left)-Math.min(foci1Left, foci2Left))
,2)
))*1000 )/1000;
  /* an exception: no major axis length! : */
  var noMajor=0;
  if(!major){major=Math.round( (semiMinor*2)*100 )/100;
  noMajor=1;};
var center=new Array(
Math.round( (((foci1Top+foci2Top)*0.5)) *100)/100,
Math.round( (((foci1Left+foci2Left)*0.5)) *100)/100
);
var semiMajor=Math.round((major/2)*1000)/1000;
while(increaseUnit>semiMajor){/*validate more*/
increaseUnit-=semiMajor;
increaseUnit=Math.round( increaseUnit*10 )/10;
};
var quadrant1=new Array(0);
var quadrant2=new Array(0);
var quadrant3=new Array(0);
var quadrant4=new Array(0);
var output=new Array(0);
//sine, cosine: are ratios/a side length:
var thetaCos=(Math.max(foci1Left,foci2Left) -
Math.min(foci1Left,foci2Left))/major;
var thetaSin=(Math.max(foci1Top,foci2Top) -
Math.min(foci1Top,foci2Top))/major;
var SMsm=semiMajor/semiMinor;
var smSM=semiMinor/semiMajor;
var prevY=0;
//run:
for(var x=semiMajor, y=0; x>=0; x-=increaseUnit, y+=increaseUnit){
if(x<0){x=0;};
if(y>semiMinor){y=semiMinor;};
  /* used formula for Y: | (b/h) * SQRT( POW(h)-POW(x) ) | */
  var Y=Math.round(
Math.abs(
(smSM)*(Math.sqrt( Math.pow(semiMajor,2) - Math.pow(x,2) ))
)*1000
)/1000;
  var X=Math.round((x*1000))/1000;
  //streamline?  
  if(!noMajor && streamline && ( (Y-prevY)>increaseUnit) ){
  Y=Math.round((y*1000))/1000;
  X=Math.round(
Math.abs(
(SMsm)*(Math.sqrt( Math.pow(semiMinor,2) - Math.pow(y,2) ))
)*1000
)/1000;
x=X;
  }
  prevY=Y;
  //build path:
var q1=++quadrant1.length-1;
var q2=++quadrant2.length-1;
var q3=++quadrant3.length-1;
var q4=++quadrant4.length-1;
  /* formulas used below for ellipse position translation from center
in Origin (G.E. Ivey):
     x'= x*cos(theta)+ y*sin(theta)
  y'= -x*sin(theta)+ y*cos (theta)
   then, I reversed signs accordingly to the 4 quadrants.
  */
var xSin=X*thetaSin;
var ySin=Y*thetaSin;
var xCos=X*thetaCos;
var yCos=Y*thetaCos;
quadrant1[q1]=new Array(2);
  quadrant1[q1][0]= Math.round( (( (-xSin) + yCos) + center[0])
*10)/10;
  quadrant1[q1][1]= Math.round( ((xCos + ySin) + center[1]) *10)/10;
quadrant2[q2]=new Array(2);
  quadrant2[q2][0]= Math.round( ( ( xSin + yCos) + center[0]) *10)/10;
  quadrant2[q2][1]= Math.round( (( (-xCos) + ySin) + center[1])
*10)/10;
quadrant3[q3]=new Array(2);
  quadrant3[q3][0]= Math.round( (( xSin + (-yCos)) + center[0])
*10)/10;
  quadrant3[q3][1]= Math.round( (( (-xCos) + (-ySin)) + center[1])
*10)/10;
quadrant4[q4]=new Array(2);
  quadrant4[q4][0]= Math.round( (( (-xSin) + (-yCos)) + center[0])
*10)/10;
  quadrant4[q4][1]= Math.round( ((xCos + (-ySin)) + center[1])
*10)/10;
}
quadrant2=quadrant2.reverse();
quadrant2.shift();
quadrant3.shift();
quadrant4=quadrant4.reverse();
quadrant4.shift();
output=output.concat(quadrant1, quadrant2, quadrant3, quadrant4);
if(!dontPopOutLast){output.pop();};
if(jumpBy){
  if(jumpBy>output.length){
  var fakeOutput=new Array(0);
  fakeOutput[++fakeOutput.length-1]=output[output.length-1];
  return fakeOutput;};
var jumpedOutput=new Array(0);
  for(var j=0; j<output.length; j+=jumpBy){
    if((j+jumpBy) > output.length-1){
    jumpedOutput[++jumpedOutput.length-1]=output[output.length-1];
    break;
    }
  jumpedOutput[++jumpedOutput.length-1]=output[j];
  }
return jumpedOutput;}
return output;
/*keep this comment to reuse freely
http://www.unitedscripters.com */} 
</script>

</HEAD>
<BODY>
<H3>Fill out the information in the boxes, then click 'draw'</H3>
Note: you need a 1 x 1 pixel black bitmap (.bmp) image in the same
directory as this file, for it to work.<p>
<FORM id="dataIn">
<table cellspacing="0" cellpadding="0">
<tr><td>Pixels down the screen, leftmost ellipse tip:  </td><td><input
type="text" length=5 value="200" id="foci2Top"></td>
<tr><td>Pixels across the screen, leftmost ellipse tip: 
</td><td><input type="text" length=5 value="100" id="foci2Left"></td>
<tr><td>Pixels down the screen, rightmost ellipse tip: 
</td><td><input type="text" length=5 value="200" id="foci1Top"></td>
<tr><td>Pixels across the screen, rightmost ellipse tip: 
</td><td><input type="text" length=5 value="300" id="foci1Left"></td>
<tr><td>Enter half the 'squashed' width of the ellipse: 
</td><td><input type="text" length=5 value="130"id="semiMinor"></td>
<tr><td><input type=button value="Draw the ellipse" onClick =
"draw()"></td><td></td>
</tr>
</form>


</body>
</html>


来源:https://stackoverflow.com/questions/11831363/draw-an-eliptical-line-on-a-coordinate-system-based-on-focla-points

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!