admin管理员组文章数量:1332383
I have a fun dev/math's problem that I can't get my head around solving.
See the illustration below.
I have two circles of dots; one small and one big.
I want to:
- Draw a line from any given point in the outer circle to any given point in the inner circle (done)
- The lines should be arcs and shouldn't cross the inner circle's boundries or the outer circle's boundries. (I need your help!)
fiddle!
I've created a jsFiddle written with RaphaelJS where i create dots and draw lines between them. See here, /.
It's basically in the drawLine
function I need your help, in order to draw a nice arc, instead of a straight line.
I added some helpers for working with vectors as well, se MathHelpers.Vector
.
Please have a go on forking and try implementing a solution where the lines bend around the. Solutions using Béziers that actually look good is also much appreciated.
And yeah, I guess vector geometry is best suited for the calculations.
Very, very, very thankful for any help. I've spent a lot of time trying to solve it, but my rusty highschool math skills just aren't enough.
I have a fun dev/math's problem that I can't get my head around solving.
See the illustration below.
I have two circles of dots; one small and one big.
I want to:
- Draw a line from any given point in the outer circle to any given point in the inner circle (done)
- The lines should be arcs and shouldn't cross the inner circle's boundries or the outer circle's boundries. (I need your help!)
fiddle!
I've created a jsFiddle written with RaphaelJS where i create dots and draw lines between them. See here, http://jsfiddle/KATT/xZVnx/9/.
It's basically in the drawLine
function I need your help, in order to draw a nice arc, instead of a straight line.
I added some helpers for working with vectors as well, se MathHelpers.Vector
.
Please have a go on forking and try implementing a solution where the lines bend around the. Solutions using Béziers that actually look good is also much appreciated.
And yeah, I guess vector geometry is best suited for the calculations.
Very, very, very thankful for any help. I've spent a lot of time trying to solve it, but my rusty highschool math skills just aren't enough.
Share edited Oct 26, 2012 at 10:06 Alex asked Oct 26, 2012 at 9:50 AlexAlex 1,74118 silver badges28 bronze badges 2- 3 You may be interested in Hohmann transfer orbits -- en.wikipedia/wiki/Hohmann_transfer_orbit – High Performance Mark Commented Oct 26, 2012 at 10:01
- 1 You should try asking in Code Golf- which is for programming puzzles and code golf. – saji89 Commented Oct 26, 2012 at 10:36
4 Answers
Reset to default 2One option is to use elliptical arcs. This doesn't look too awesome, but satisfies the constraints, and I think it can be improved by careful choice of the circle radius (here I used a fixed one).
var angleDiff = MathHelpers.getAngleInCircle(innerCircleIndex, numberOfDotsInInnerCircle) - MathHelpers.getAngleInCircle(outerCircleIndex, numberOfDotsInOuterCircle);
while (angleDiff > Math.PI) {
angleDiff -= 2 * Math.PI;
}
while (angleDiff < -Math.PI) {
angleDiff += 2 * Math.PI;
}
from = addOffsetAndRound(from);
to = addOffsetAndRound(to);
r = (0.5 * innerCircleRadius + 0.5 * outerCircleRadius);
var pathStr = "";
pathStr += "M" + [from.x, from.y].join(' '); // MOVE to
pathStr += "A" + [r, r, 0, 0, angleDiff >= 0 ? 1 : 0, to.x, to.y].join(' '); // Draw line to
var path = paper.path(pathStr);
P.S. Of course, one should keep in mind that the real spiral isn't an elliptical arc.
Start simply by drawing a piecewise a spiral.
The spiral radius goes from start angle to end angle and the spiral radius goes from inner circle radius to outer circle radius.
To give you an idea of what I mean, choose a number of pieces (n)
var n = 20, // The number of lines in the spiral
rStep = (outerRadius - innerRadius)/n, // the radius increase between points
aStep = (outerAngle - innerAngle)/n, // the angle change between points
points = [];
// pute the cartesian coordinates (x, y) from polar coordinates (r, a)
function cartesian(r, a) {
return [
r * Math.cos(a),
r * Math.sin(a)
];
}
for (i = 0; i <= n; i += 1) {
points.push(cartesian(innerRadius + (i * rStep), innerAngle + (i * aStep));
}
I have demonstrated a basic piecewise spiral using polar coordinates:
http://jsfiddle/xmDx8/
Try changing n to see how the pieces build up.
drawLine(innerCircleIndex, outerCircleIndex, 1); // This is what you did
drawLine(innerCircleIndex, outerCircleIndex, 100); // 100 lines in the example
drawLine(innerCircleIndex, outerCircleIndex, n); // Choose n to see how it grows
If you really did want to avoid teh fancy maths, you could approximate a spiral using a series of simple line segments given no information other than the coordinates of the two points being connected and either their respective angles relative to the origin or the origin's coordinates (obviously one can be inferred from the other). Given (ix,iy,i_angle) describing the coordinates and relative angle of the interior point and (ox,oy,o_angle) describing the coordinates and relative angle of the exterior point,
var generatePath = function( ix, iy, i_angle, ox, oy, o_angle )
{
var path = [ "M", ox, oy ];
var slices = 100;
var cur_angle = o_angle;
var cur_r = cr_outer;
var delta_r = ( cr_inner - cr_outer ) / slices;
var delta_angle = ( i_angle - o_angle );
if ( delta_angle > Math.PI )
delta_angle -= Math.PI * 2;
else if ( delta_angle < Math.PI * -1 )
delta_angle += Math.PI * 2;
delta_angle = delta_angle / slices;
for ( var i = 0; i < slices; i++ )
{
cur_angle += delta_angle;
cur_r += delta_r;
path.push( "L", cx + Math.cos( cur_angle ) * cur_r, cy + Math.sin( cur_angle ) * cur_r );
}
return path;
}
The logic is stupid-simple, looks good even at high resolutions, and is possibly more performant than a "genuine" arc segment or series of quadratic bezier curve. The number of slices per segment could probably be tuned based on length and size to balance performance against aesthetics.
I have this function (with control point calculations) staged here.
Trying an approach without fancy maths:
- find the outter dot and the inner dot that are halfway between the dots to connect.
- find the middle of the segment formed by these halfway dots.
Draw your curve passing by this point.
本文标签: Challenging vector maths in JavaScriptStack Overflow
版权声明:本文标题:Challenging vector maths in JavaScript - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1742295024a2448549.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论