РЕДАКТИРОВАТЬ: мой (принятый) ответ был плохим.Это исправляет это:
Предполагается, что r будет от 1 до 5. Преобразуйте мышь декартовой mx, my в полярную mr, mt.Сначала проверьте, близок ли г-н к 1 из 5 радиусов.Функция checkr делает это.Если он близок, то проверьте, близок ли m к 1 из 24 тэт.Функция checkt делает это.Сложность состоит в том, что функция atan2 не является непрерывной в pi радианах, где находятся точки, поэтому делайте разрыв в -pi / 24 радианах, где нет точек.
Значение "close" равно pi /24, поскольку расстояние дуги между двумя соседними точками в точке r = 1 будет равным pi / 12.
var del = 1*Math.PI/24*.7; // for example
function xy2rt(xy) { // to polar cordinates
var rt = [];
rt.push(Math.sqrt(xy[0]*xy[0]+xy[1]*xy[1])); // r
var zatan = Math.atan2(xy[1], xy[0]);
// make the discontinuity at -pi/24
if (zatan < -Math.PI/24) zatan += 2*Math.PI;
rt.push(zatan); // theta
return rt;
}
function checkr() { // check radial distance
for (var pr=1; pr<=5; pr+=1) { // 5 radii
if (Math.abs(mr-pr) < del) { checkt(pr); break; }
}
}
function checkt(pr) { // check theta
var pt;
for (var ipt=0; ipt<24; ipt+=1) { // 24 thetas
pt = ipt / 24 * 2 * Math.PI;
if (Math.abs(mt-pt) < del/pr) {
// is close -- do whatever
break;
}
}
}
Моя проблема заключалась в проверке расстояния дуги, я использовал mr и pr, тогда как должен использоваться только pr.ОП обнаружил мою ошибку, обработав каждый пиксель на холсте, и обнаружил, что возникла проблема.Я также обработал каждый пиксель, и это изображение показывает процедуры, чтобы быть правильными сейчас.Черный цвет - это место, где процедуры определяют, что пиксель близок к одной из 120 точек.
РЕДАКТИРОВАТЬ: Ускоренная обработка
Выполняется много математических функций *.Хотя я ничего не рассчитывал, я думаю, что это должно быть намного быстрее.
1) Координаты x, y из 120 точек сохраняются в массивах.
2) Вместо того, чтобы получать полярные значения mr, mt, pr, и pt, используйте векторную обработку.
Здесь вывод дуги, расстояние дуги с использованием векторов.
sint = sin(theta) = (M cross P)/mr/pr (cross product Mouse X Point)
cost = cos(theta) = (M dot P)/mr/pr (dot product Mouse . Point)
sint will be used to get arc distance, but sint goes to zero at theta=+-pi as well as theta=0, so:
mdotp will be used to determine if theta is near zero and not +-pi
arcd = pr*theta
arcd = pr*sin(theta) (good approximation for small theta)
arcd = pr*abs(M cross P)/mr/mp (from above)
if ardd < del, check if mdotp > 0.
Вот массивы load-xy и новые процедуры checkr и checkt.
apx=[], apy=[]; // the saved x,y of the 120 points
function loadapxapy() { // load arrays of px, py
var itheta, theta
for (var pr=1; pr<=5; pr+=1) { // 2-dimension arrays
apx[pr] = []; apy[pr] = []; // 5 arrays, 1 for each pr
for (itheta=0; itheta<24; itheta+=1) { // 24 x's and y's
theta = Math.PI*itheta/12;
apx[pr][itheta] = pr*Math.cos(theta);
apy[pr][itheta] = pr*Math.sin(theta);
}
}
}
function checkr() { // check radial distance
var mr = Math.sqrt(mx*mx+my*my); // mouse r
for (var pr=1; pr<=5; pr+=1) { // check 1 to 5
if (Math.abs(mr-pr) < del) { // mouser - pointr
checkt(mr, pr); // if close, check thetas
}
}
}
function checkt(mr, pr) { // check thetas
var px, py, sint, mdotp, arcd;
for (var itheta=0; itheta<24; itheta+=1) { // check 24
px = apx[pr][itheta]; // get saved x
py = apy[pr][itheta]; // and y
// This arcd is derived from vector processing
// At least this doesn't use the accursed "atan"!
sint = Math.abs(mx*py-my*px)/mr/pr; // sine
arcd = pr*sint; // arc distance
if (arcd<del) { // arc distance check
mdotp = (mx*px+my*py); // final check
if (mdotp > 0) { // to see if theta is near zero and not +-pi
setpixelxy([mx, my]); // or whatever..
}
}
}
}