Ru-Board.club
← Вернуться в раздел «Прикладное программирование»

» JavaScript и Canvas: архимедова спираль

Автор: GeMir
Дата сообщения: 12.03.2013 03:29
Собственно, есть потребность нарисовать в Canvas архимедову спираль, начинающуюся в произвольной точке.
Если рисовать "изнутри наружу", проблем особых не возникает:

Код: context.moveTo(start_x, start_y)
context.beginPath()    
        
for (angle = 0; angle < Math.PI*6; angle = angle+0.01) {
                
x = start_x + (a + b * Math.pow(angle, p)) * Math.cos(angle)
y = start_y + (a + b * Math.pow(angle, p)) * Math.sin(angle)

context.lineTo(x, y)
}
                
context.lineWidth = 0.25;
context.strokeStyle = "#fff"
context.stroke()
Автор: Cheery
Дата сообщения: 12.03.2013 04:23
GeMir
Javascript в другом разделе обсуждают )
Да и для "рисования" он не очень то подходит, если только в канвасе.


Цитата:
Если рисовать "изнутри наружу", проблем особых не возникает:

а в чем проблема снаружи?

"двигаете" точку равномерно вдоль прямой, для каждой точки пересчитываете положение в полярных координатах и все..

http://jsfiddle.net/JWU4z/

ну или если хочется в другом направлении, то
http://jsfiddle.net/JWU4z/1/


Код: var r = 100, dr = -0.1, k = 0.4,
shiftX = 100, shiftY = 100;
while (r > 0) {
var x = r * Math.cos(k * r),
y = r * Math.sin(-k * r);
var div = document.createElement('div');
div.className = 'dot';
div.style.left = x + shiftX + 'px';
div.style.top = y + shiftY + 'px';
document.body.appendChild(div);
r += dr;
}
Автор: GeMir
Дата сообщения: 12.03.2013 22:29
Cheery

Цитата:
а в чем проблема снаружи?

В том, что принцип конструирования спирали "вручную" знаю и понимаю, а вот в код перевести пока не выходит.

Цитата:
http://jsfiddle.net/JWU4z/

В этих примерах координаты центра задаются.
Мне же хотелось бы задавать координаты конечной точки.
Автор: Cheery
Дата сообщения: 12.03.2013 22:48
GeMir

Цитата:
В этих примерах координаты центра задаются.  
Мне же хотелось бы задавать координаты конечной точки.

?? конечная точка в центре координатной системы? подробнее, не нужно же вытягивать все из вас ?)
Автор: GeMir
Дата сообщения: 12.03.2013 22:55
Cheery

Цитата:
конечная точка в центре координатной системы?

В центре координатной системы — полюс (красная точка). С него обычно и начинают рисовать спираль.
Но мне нужно рисовать начиная с "конца" (зелёная точка).

Автор: Cheery
Дата сообщения: 12.03.2013 22:58
GeMir

Цитата:
Но мне нужно рисовать начиная с "конца" (зелёная точка).

я все равно не понимаю в чем ваша проблема? вы хотите, чтобы рисунок начинался откуда то еще? то есть добавить фазу к углу?

или задать начальные координаты, а не r, как у меня в коде?


Цитата:
В этих примерах координаты центра задаются.  

неправда.. задается смещение, чтобы видна была вся спираль (иначе будет видна только четверть, остальное будет за пределами окна)..
рисуется от внешней точки к центру
Автор: GeMir
Дата сообщения: 12.03.2013 23:04
Cheery
Ок, кажется понял, в чём недопонимание.
Да, мне нужно иметь возможность задать координаты конечной (зелёной) точки.

Цитата:
задается смещение

Которое, для того, чтобы спираль была видна целиком, должно быть больше или равно радиусу.
Полюс спирали при этом будет в точке с координатами (shiftX; shiftY).
Автор: Cheery
Дата сообщения: 12.03.2013 23:10
GeMir

Цитата:
Да, мне нужно иметь возможность задать координаты конечной (зелёной) точки.

так в чем сложность то ?)
задали x и y (относительно центра координат), тогда r = sqrt(x^2 + y^2)
а дальше уже зависит от того, что надо - ведь не факт, что эта точка попадет на нужную спираль.. а значит либо из нее нужно рассчитывать коэффициент для спирали, чтобы она проходила через точку. либо поворачивать спираль - то есть ввести фазу для угла

ps: это то понятно как делать ?)
Автор: GeMir
Дата сообщения: 13.03.2013 00:59
Cheery

Цитата:
это то понятно как делать ?)

Если честно, то нет. Говорю же — туплю :/
Автор: Cheery
Дата сообщения: 13.03.2013 02:39
GeMir

Цитата:
Если честно, то нет. Говорю же — туплю

http://jsfiddle.net/JWU4z/3/


Код: var iniX = -100, iniY = -100, dr = -0.05, n = 2 /* число витков до точки (не включая ее) */,
shift = r = Math.sqrt(iniX * iniX + iniY * iniY), k;
/* подсчитаем угол и коэффициент k */
var angle = Math.atan2(iniY, iniX);
angle += angle < 0 ? 2 * Math.PI : 0;
k = (angle + 2 * Math.PI * n) / r;

while (r > 0) {
var x = r * Math.cos(k * r),
y = r * Math.sin(-k * r);
var div = document.createElement('div');
div.className = 'dot';
div.style.left = x + shift + 'px';
div.style.top = y + shift + 'px';
document.body.appendChild(div);
r += dr;
}
Автор: GeMir
Дата сообщения: 23.03.2013 04:32
"А ларчик просто открывался". Рисовать спираль из конечной точки так и не понадобилось:

[more]
Код: var PI = Math.PI

function drawAnimatedDots() {

    var arrow_context = $("layer_1").getContext("2d")
    var context = $("layer_2").getContext("2d")
        
    var canvas_width = context.canvas.width
    var canvas_height = context.canvas.height
    var start_x = canvas_width/2
    var start_y = canvas_height/2
        
    var length = 350
    var step = 30
    var angle = 0
    var rotation_angle = (-1)*Math.asin(step / Math.sqrt(Math.pow((length-step), 2) + Math.pow(step, 2)))

    var factor = 1 - step/length
        
    function drawFourDots(context, radius, colour, arrow_length, arrow_width, arrow_colour) {
            
        if (length <= 60) {
            window.clearInterval(animation)    
            is_drawing = false
        } else {
            x_1 = start_x + length*Math.cos(PI/4+angle)
            y_1 = start_y + length*Math.sin(PI/4+angle)

            x_2 = start_x + length*Math.cos(3*PI/4+angle)
            y_2 = start_y + length*Math.sin(3*PI/4+angle)
                
            x_3 = start_x + length*Math.cos(5*PI/4+angle)
            y_3 = start_y + length*Math.sin(5*PI/4+angle)

            x_4 = start_x + length*Math.cos(7*PI/4+angle)
            y_4 = start_y + length*Math.sin(7*PI/4+angle)
            
            // Draw arrows on a sub-layer
            drawArrow(arrow_context, x_1, y_1, arrow_length, arrow_width, (3*PI/2)+angle, arrow_colour)        
            drawArrow(arrow_context, x_2, y_2, arrow_length, arrow_width, angle, arrow_colour)
            drawArrow(arrow_context, x_3, y_3, arrow_length, arrow_width, (PI/2)+angle, arrow_colour)
            drawArrow(arrow_context, x_4, y_4, arrow_length, arrow_width, PI+angle, arrow_colour)
                
            // Draw dots
            drawDot(context, x_1, y_1, radius, "#00aae8")
            drawDot(context, x_2, y_2, radius, "#aae800")
            drawDot(context, x_3, y_3, radius, "#e800aa")
            drawDot(context, x_4, y_4, radius, "#e8aa00")
                
            angle = (angle + rotation_angle) / factor
            length = length * factor
        }
    }
    animation = window.setInterval(function (){drawFourDots(context, 3, "#fff", 15, 1.5, "#666")}, 250)        
}

Страницы: 1

Предыдущая тема: EOleSysError Класс не зарегистрирован.


Форум Ru-Board.club — поднят 15-09-2016 числа. Цель - сохранить наследие старого Ru-Board, истории становления российского интернета. Сделано для людей.