Как узнать координаты нужной точки рисунка?

kypm

Я новичок в программировании, не сочтите вопрос провокационным или вызванным ленью...Я нарисовал окружность и разделил ее на пять равных частей:
CLS
SCREEN 12
k = .017453
FOR i = 5 TO 1 STEP -1
  CIRCLE (300, 200), 200, i + 9, 72 * k, 72 * i * k
NEXT i
Как мне узнать координаты точек начала каждого сектора для дальнейших построений?Неужели методом тыка?
14 ответов

kypm

Круговую диаграмму хотите?))))
    CONST pi = 3.141592653589793#
    CONST Gradus = pi / 180, RAD = 180 / pi
 
SCREEN 12
' то же самое параметрически:
 ' Центр
cx = 320
cy = 240
r = 200
  x = cx + r: y = cy
  xD = cx + r: yD = cy
FOR i% = 0 TO 360
  ff! = i%
  xn = cx + COS(ff! * Gradus) * r: yn = cy - SIN(ff! * Gradus) * r
  LINE (x, y)-(xn, yn), ((i% - 1) \ 72) + 9
  IF i% MOD 72 = 0 THEN
    LINE (xn, yn)-(cx, cy), ((i% - 1) \ 72) + 9
    LINE (xD, yD)-(cx, cy), ((i% - 1) \ 72) + 9
    PAINT ((xn + cx + xD) / 3, (yn + cy + yD) / 3), ((i% - 1) \ 72) + 9, ((i% - 1) \ 72) + 9
    xD = xn: yD = yn
  END IF
  x = xn: y = yn
NEXT
Неужели методом тыка?
Кстати говоря, очень хороший метод, я помню лет 8 назад, когда проги для воспроизведения Wav из спикера писал уповал только на него)))))), в итоге полностью разобрался как эта шняга работает на физическом уровне. Только лучше юзать не просто метод тыка, а метод "научного тыка" в совокупности с методом исключений, работает безотказно))))


kypm

2 Quiet Snow:Ваша прога очень красива и познавательна, но где же координаты точек???Я, собственно, пример с окружностью привел только для иллюстрации, вопрос мой шире:Есть ли способ средствами Кубасика узнавать координаты любой точки на графическом экране?У меня такая мысль: Как сделать простейший указатель и подводить его к нужной точке, я догадываюсь, вопрос только: как заставить прогу сообщать текущее положение указателя? Можно в режиме реального времени.Но, возможно, все намного проще, и Кубасик сам это умеет?Снова Quiet Snow:Я чуть доработал вашу программу:
CONST pi = 3.141592653589793#
    CONST Gradus = pi / 180, RAD = 180 / pi
 
SCREEN 12
' то же самое параметрически:
 ' Центр
cx = 320
cy = 240
r = 200
  x = cx + r: y = cy
  xD = cx + r: yD = cy
FOR i% = 0 TO 360
  ff! = i%
  xn = cx + COS(ff! * Gradus) * r: yn = cy - SIN(ff! * Gradus) * r
  LINE (x, y)-(xn, yn), ((i% - 1) \ 72) + 9
  IF i% MOD 72 = 0 THEN
    LINE (xn, yn)-(cx, cy), ((i% - 1) \ 72) + 9
    LINE (xD, yD)-(cx, cy), ((i% - 1) \ 72) + 9
    'PAINT ((xn + cx + xD) / 3, (yn + cy + yD) / 3), ((i% - 1) \ 72) + 9, ((i% - 1) \ 72) + 9
    xD = xn: yD = yn
  END IF
  x = xn: y = yn
NEXT
 
PRINT x
PRINT y
CIRCLE (x, y), 20
В таком виде, меняя параметр i% , вместо 360 на нужную величину, например 72, можно получать координаты нужных точек.Спасибо!


kypm

Есть ли способ средствами Кубасика узнавать координаты любой точки на графическом экране?
Вам должно быть понятно как пишутся такие программы, окружность это графический элемент, процедура CIRCLE только её рисует, точки из этой процедуры получить нельзя. Поэтому я заменил процедуру CIRCLE на свою, которая рисует окружность коротенькими линиями между точками (x, y) - старые координаты и (xn, yn) - новые координаты, после отрисовки кусочка в 1 градус старым координатам присваиваются значения новых, цикл переходит на новую величину угла и (xn, yn) считаются заново.
В таком виде, меняя параметр i% , вместо 360 на нужную величину, например 72, можно получать координаты нужных точек.
Никаких i% менять не надо вот формула:
xn = cx + COS(ff! * Gradus) * r: yn = cy - SIN(ff! * Gradus) * r
посмотрите внимательно код, разберитесь как он работает, посмотрите графики тригонометрических функций SIN и COS.


kypm

Quiet Snow, большое спасибо за науку. Я вполне понял ваш подход и хорошо помню что такое sin и kos.Благодаря вашему руководству я за сегодняшний день сделал две программы (первые в жизни!).В первой я объединил ваш метод вычисления координат со своим методом рисования секторов окружностей. Выдает координаты автоматически:
CLS
SCREEN 12
'center
cx = 300
cy = 200
r = 200
k = .017
FOR i = 1 TO 5
   xn = cx + COS(i * 72 * k) * r
   yn = cy - SIN(i * 72 * k) * r
   CIRCLE (300, 200), 200, , 72 * k, 72 * i * k
     PRINT xn
     PRINT yn
     PRINT "---"
     CIRCLE (xn, yn), 10
NEXT i
Вторая программа позволяет стрелочками подвести указатель к нужной точке рисунка и , нажав клавишу "р", узнать ее координаты:
CLS
SCREEN 12
k = .017453
 
FOR i = 5 TO 1 STEP -1
  CIRCLE (300, 200), 200, i + 9, 72 * k, 72 * i * k
NEXT i
 
PSET (x, y), 3
CIRCLE (x - 1, y - 1), 2, 0
1 A$ = INKEY$
IF A$ = "" THEN 1
IF A$ = CHR$(0) + CHR$(72) THEN y = y - 1
IF A$ = CHR$(0) + CHR$(80) THEN y = y + 1
IF A$ = CHR$(0) + CHR$(77) THEN x = x + 1
IF A$ = CHR$(0) + CHR$(75) THEN x = x - 1
IF A$ = "p" THEN PRINT x: PRINT y
IF A$ = "q" THEN STOP
PSET (x, y), 3
CIRCLE (x - 1, y - 1), 2, 0
GOTO 1


kypm

(первые в жизни!)
Для первых в жизни впечатляет...
В первой я объединил ваш метод вычисления координат со своим методом рисования секторов окружностей.
1) Процедуры CIRCLE я бы на вашем месте убрал. Так всего лишь совет...2) k = .017 Не стоит пренебрегать точностью, это уже будет достаточно заметно, проведите опыт обрисуйте CIRCLE по формуле и увидите разницу(гляньте как в моей проге задано pi и 1 градус).


kypm

Для графического экрана точность и так чрезмерная, ведь дробных пикселей не существует!


kypm

Для графического экрана точность и так чрезмерная
Ошибаетесь, обрисуйте окружность с выводом координат, если будут значительные отличия, значит точность плохая(угловая, но всё же). Ещё вы можете обрисовать радиусом > 5000 и ваша точность размажет координаты вмясо, там уже даже не десяток а больше пикселей будет несоответствие. Ни о какой точности уже и говорить не придётся. С несоответствиями нужно бороться. К тому же не вижу смысла юзать FP при таком подходе, я к примеру могу и на целочисленной арифметике достаточно большую точность иметь.
ведь дробных пикселей не существует!
Зато есть алгоритмы которые могут это учесть и меняют освещённость пикселей в зависимости от логического расположения объекта. Пример - сглаживание векторного шрифта. Про это вам ещё рано думать, но знать желательно. Уж там точность пипец как важна.Вот кстати полюбуйтесь:
    CONST pi = 3.141592653589793#
    CONST Gradus = pi / 180, RAD = 180 / pi
SCREEN 12
cx = 3800
cy = 3800
r = 5000
Gradus2 = .017   ' Ваш коеф-т
  x = cx + r: y = cy
  x2 = cx + r: y2 = cy
  xD = cx + r: yD = cy
FOR i% = 0 TO 360
  ff! = i%
  xn = cx + COS(ff! * Gradus) * r: yn = cy - SIN(ff! * Gradus) * r
  xn2 = cx + COS(ff! * Gradus2) * r: yn2 = cy - SIN(ff! * Gradus2) * r
  LINE (x, y)-(xn, yn), 7
  LINE (x2, y2)-(xn2, yn2), 10
  CIRCLE (x2, y2), 5, 10
  CIRCLE (x, y), 5, 12
  x = xn: y = yn
  x2 = xn2: y2 = yn2
NEXT


kypm

Точность - хорошая штука, и в ряде случаев необходимая. Глупо было бы спорить. Но и из пушки по воробям палить тоже непродуктивно. Ваша иллюстрация скорее говорит о том, что для экрана 620х450, коэффициент 0.17 - весьма хорошее приближение, если рисовать звездочки и пятиугольники. Что я собственно и собирался делать поначалу.Я оценил также преимущества вашего метода построения окружностей, он , в частности, позволяет построить окружность, с началом от оси y, а не от оси х, как метод CIRCLE.Но мне все-таки хотелось бы получать текущие координаты точек хn, yn для определенных значений i%. Напечатать их на экране можно, но лучше бы иметь переменные х1, х2, х3... и т.д. со значениями через каждые 72 градуса. Как бы это сделать?. А затем их нужно округлить до целых чисел.
CONST pi = 3.141592653589793#
CONST Gradus = pi / 180, RAD = 180 / pi
CLS
SCREEN 12
cx = 320
cy = 240
r = 200
x = cx: y = cy
FOR i = 0 TO 360
  xn = cx - SIN(i * Gradus) * r: yn = cy - COS(i * Gradus) * r
  LINE (x, y)-(xn, yn)
  IF i MOD 72 = 0 THEN
   LINE (xn, yn)-(cx, cy)
   PRINT xn: PRINT yn: PRINT ""
   'вот здесь бы разместить вместо предыдущей строки
   'некую переменную, "запоминающую" текущее значение xn и yn,
   'типа xi, yi
   'xi = xn: yi = yn
  END IF
  x = xn: y = yn
NEXT i
'LINE (x72, y72)-(x144, y144)
Кстати, хотел вас спросить, зачем нужны все эти избыточные переменые, вроде ff! = i%; xD и так далее?


kypm

зачем нужны все эти избыточные переменые, вроде ff! = i%; xD и так далее?
Не обращайте внимания. Точнее уберите их, они там действительно не нужны и вместо ff! в формуле напишите i%... Сам не знаю нафига я такую чушь сморозил))))), старею блин...
Ваша иллюстрация скорее говорит о том, что для экрана 620х450, коэффициент 0.17 - весьма хорошее приближение
Моя иллюстрация говорит о том что когда вы будете писать более "крутые" программы и вращать точки, это будет мягко говоря "неточно", ещё это говорит о том что всё равно бейсик считает Floating Point числа, перемножить более точное число или менее точное ему абсолютно без разницы. Разрешение экрана кстати 640х480 точек)))), это 16 цветный стандарт VGA.
Но мне все-таки хотелось бы получать текущие координаты точек хn, yn для определенных значений i%.
Вот формула посмотрите её ещё раз внимательно:
xn = cx + COS(i% * Gradus) * r
yn = cy - SIN(i% * Gradus) * r
Вам нужно получить пятиугольник, т.е. этой формулой посчитать значения i% равные, 0, 72, 144, 216, 288. Значение 360 будет равно значению 0 градусов, а ноль у нас уже есть. Заведём массив и заполним его:
CONST pi = 3.141592653589793#, Gradus = pi / 180
CONST deleniye = 72, chastey = (360 \ deleniye) - 1
 DIM xm%(chastey), ym%(chastey)
cx = 320: cy = 240: r = 150
 FOR i% = 0 TO chastey
xm%(i%) = cx + COS(i% * Gradus * deleniye) * r
ym%(i%) = cy - SIN(i% * Gradus * deleniye) * r
 NEXT
  ' Вывод точек
 SCREEN 12
 FOR i% = 0 TO chastey
  CIRCLE (xm%(i%), ym%(i%)), 5, 15
   FOR j% = 0 TO i%
    LINE (xm%(i%) + 10 + j% * 2, ym%(i%) - 10)-(xm%(i%) + 10 + j% * 2, ym%(i%))
   NEXT
 NEXT


kypm

Замечательно, пронумеровали точки. Очень интересный подход, буду знать.Но я-то и так знаю, какая из точек первая, какая вторая и так далее...Мне бы их соединить между собой , чтобы получился пятиугольник, или там звезда. И не вручную, а чтобы программа строила. Для этого нужны текущие координаты. Нельзя ли их получить подобным способом?


kypm

чтобы получился пятиугольник, или там звезда.
Ну пятиугольник просто, строите оператором LINE в цикле. Координаты у вас есть(в массиве). Насчёт звезды не знаю, там думать надо какую точку с какой соединять.
Для этого нужны текущие координаты.
Что по вашему означает текущие координаты? Может я вас не правильно понимаю? Формула даёт координаты окружности. Вы вбиваете центр, радиус, отклонение в градусах и получаете экранные координаты. По ним можно строить нужную фигуру.
И не вручную, а чтобы программа строила.
Допишите это в конец прошлой программы:
 FOR i% = 0 TO chastey
    LINE (xm%(i%), ym%(i%))-(xm%(i%+1 mod chastey), ym%(i%+1 mod chastey)), 10
 NEXT
Извините, я ступил, вот прога для пятиугольника :
CONST pi = 3.141592653589793#, Gradus = pi / 180
CONST deleniye = 72, chastey = (360 \ deleniye) - 1
 DIM xm%(chastey), ym%(chastey)
cx = 320: cy = 240: r = 150
 FOR i% = 0 TO chastey
xm%(i%) = cx + COS(i% * Gradus * deleniye) * r
ym%(i%) = cy - SIN(i% * Gradus * deleniye) * r
 NEXT
  ' Вывод линий
SCREEN 12
FOR i% = 0 TO chastey
 LINE (xm%(i%), ym%(i%))-(xm%((i% + 1) MOD (chastey + 1)), ym%((i% + 1) MOD (chastey + 1))), 10
NEXT
а если LINE на это замените будет звезда(пентограмма)
 LINE (xm%(i%), ym%(i%))-(xm%((i% + 2) MOD (chastey + 1)), ym%((i% + 2) MOD (chastey + 1))), 10


kypm

Спасибо, сейчас уже поздно, поэтому я отложу удовольствие разобраться в ваших программах на завтра.А сегодня я промучился целый день, но заставил прогу строить звезду - таки. Пятиугольник -то проще, сразу вышел. А что означает MOD применительно к частям? В прошлый раз вы его употребили как признак делимости.Завтра напишу подробнее.P.S. Пентаграмма и звезда - весьма разные вещи. Я так думаю...


kypm

А что означает MOD применительно к частям?
Это чтобы номер точки не превышал количество частей(линий), т.к. в цикле мы должны отрисовать 5 линий то i% + 1 будет равно 6, т.е. больше кол-ва частей, следовательно нас ждёт ошибка на стадии работы программы. Чтобы убрать эту лажу и правильно отрисовать линию я добавил mod, 6-я точка становится нулевой и соединение проходит по кругу(т.е. как нам и надо). Оператор MOD выдаёт остаток от деления.точнее там от нуля отсчёт ведётся...


kypm

Извините за промедление, насилу справился...Вот что вышло в результате нашего совместного труда:
CLS
INPUT "Print the number of star ends (only odd [nechetnye] numbers starting from 5) "; L
CONST pi = 3.14159265#
CONST gr = pi / 180
'variables:
cx = 320
cy = 240
r = 200
'L= number of star ends from input
om = ((L + 1) / 2) - 1
 
DIM xn(720), yn(720)
 
FOR i = 0 TO 720
  xn(i) = cx - SIN(i * gr) * r
  yn(i) = cy - COS(i * gr) * r
NEXT i
 
SCREEN 12
 
FOR i = 0 TO 720
  PSET (xn(i), yn(i)), 2
NEXT
 
FOR i = 0 TO L
  LINE (xn(i * 360 / L), yn(i * 360 / L))-(xn((i + om) * 360 / L), yn((i + om) * 360 / L)), 3
NEXT
Хотел сделать exe файл, чтобы снять скриншоты, но почему-то не получается.Большое спасибо вам за руководство!