Фракталы в AutoLISP
| Правила | Регистрация | Пользователи | Сообщения за день |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Фракталы в AutoLISP

Фракталы в AutoLISP

Ответ
Поиск в этой теме
Непрочитано 13.11.2010, 13:19 #1
Фракталы в AutoLISP
Seregarival
 
Регистрация: 13.11.2010
Сообщений: 15

Преподаватель дал задание нарисовать фрактал "Шестиугольник Серпинского", но сам он немного понимает в Автокад/ЛИСП, ничего толком не объяснил.
В общем суть проблемы в том, что в Lisp из AutoCAD2010 нет случайных чисел, а фрактал использует их... В итоге я узнал, что в AutoCAD2007 они есть, не могли бы подсказать как правильно их использовать, функция rnd не работает....
Для создания фрактала нужно нарисовать шестиугольник, потом выбирается случайная точка О внутри него, и ставится точка на середине отрезка от данной точки О до произвольной вершины, потом опять выбирается произвольная вершина и ставится точка на середине отрезка.... в общем без случайных чисел никак...
Сам плохо пока знаю LISP, нужна помощь:

(DEFUN F()
;(Setq X 50)
;(Setq Y 150)
(Setq A '(50 150))
(Setq B '(100 250))
(Setq C '(200 250))
(Setq D '(250 150))
(Setq E '(200 50))
(Setq F '(100 50))
;(Setq O '((Rnd 200) (Rnd 200)))
(Command "_Line" A B C D E F A "")
) Пока только начало кода, но без помощи дальше уже никак...
Как уже написал Rnd не работает и еще один косяк:
(Setq X 50)
(Setq Y 150)
(Setq A '(X Y))
Почему такая конструкция не работает?
Помогите, пожалуйста!
Просмотров: 9458
 
Непрочитано 13.11.2010, 13:25
#2
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Генератор случайных чисел:
Код:
[Выделить все]
(defun rng (/ modulus multiplier increment rand)
;;; Генерирует псевдослучайное число от 0.0000000 до 0.9999999
  (if (not seed)
	(setq seed (getvar "DATE"))
  )
  (setq
	modulus    4294967296.0 ; 65536
	multiplier 1664525      ; 25173
	increment  1            ; 13849
	seed (rem (+ (* multiplier seed) increment) modulus)
	rand (/ seed modulus)
  )
)
gomer вне форума  
 
Автор темы   Непрочитано 13.11.2010, 13:31
#3
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Спасибо, насколько я понял, этот генератор будет работать и в 2010 версии?
Подскажите пожалуйста как им правильно пользоваться и можно ли сделать, чтобы числа были от 0 до заданного, например до 6 или 200?
Seregarival вне форума  
 
Непрочитано 13.11.2010, 13:40
#4
AlexV

Инженер
 
Регистрация: 02.10.2008
С-Пб
Сообщений: 3,692


Цитата:
"Генерирует псевдослучайное число от 0.0000000 до 0.9999999"
, следовательно что бы получить диапазон от нуля до нужного числа, то результат функции надо на это число умножить, по идее?
__________________
...Не пытайся гнуть ты ложку,
Не вяжи её узлом.
Ложка - ложка понарошку,
А по правде, - это лом!
AlexV вне форума  
 
Непрочитано 13.11.2010, 13:48
#5
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


и пофиксить
gomer вне форума  
 
Непрочитано 13.11.2010, 14:00
#6
VVA

Инженер LISP
 
Регистрация: 11.05.2005
Минск
Сообщений: 6,996


Посмотри еще здесь
Fractals
Attractors
Iterated Function Systems
Fractal Tree
__________________
Как использовать код на Лиспе читаем здесь
VVA вне форума  
 
Автор темы   Непрочитано 13.11.2010, 14:46
#7
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Код:
[Выделить все]
(DEFUN F()
  (Setq X 50)
  (Setq Y 150)
  (Setq A '(50 150))
  (Setq B '(100 250))
  (Setq C '(200 250))
  (Setq D '(250 150))
  (Setq E '(200 50))
  (Setq F '(100 50))
  (Setq O '((Rng) (Rng))
  (Command "_Line" A B C D E F A "")
  (Command "_Line" A O "")


(defun rng (/ modulus multiplier increment rand)
;;; Генерирует псевдослучайное число от 0.0000000 до 0.9999999
  (if (not seed)
	(setq seed (getvar "DATE"))
  )
  (setq
	modulus    4294967296.0 ; 65536
	multiplier 1664525      ; 25173
	increment  1            ; 13849
	seed (rem (+ (* multiplier seed) increment) modulus)
	rand (/ seed modulus)
  )
)
	 
)
; ошибка: неверно сформирванный список на входе
Он не генрирует почему-то даже... я наверное что-то не так делаю?
Seregarival вне форума  
 
Непрочитано 13.11.2010, 15:04
#8
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Естественно, скобки нужно закрывать!!!
и еще:
Код:
[Выделить все]
(setq O (mapcar '(lambda (x)(fix(* x 200)))(list (Rng) (Rng))))
gomer вне форума  
 
Автор темы   Непрочитано 14.11.2010, 08:44
#9
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Код:
[Выделить все]
(DEFUN F()
  (Setq X 50)
  (Setq Y 150)
  ;для начала нарисуем шестиугольник
  (Setq A '(50 150))
  (Setq B '(100 250))
  (Setq C '(200 250))
  (Setq D '(250 150))
  (Setq E '(200 50))
  (Setq F '(100 50))
  (Command "_Line" A B C D E F A "")
  ;далее внутри него нарисуем произвольную точку
  (setq O (mapcar '(lambda (x)(fix(* x 200)))(list (Rng) (Rng))))
  ;Организуем цикл для построения множества точек
  (REPEAT 100
  (
  	;выберем произвольную вершину
  	(Setq R (mapcar '(lambda (x)(fix(* x 6)))(Rng)))
  	(if (> R 0)
  		(Setq T A))
  	(if (> R 1)
  		(Setq T B))
  	(if (> R 2)
  		(Setq T C))
  	(if (> R 3)
  		(Setq T D))
  	(if (> R 4)
  		(Setq T E))
  	(if (> R 5)
        	(Setq T F))
  	;поставим точку на середине отрезка между выбранной точкой и произвольной вершиной
  	(SetQ P
  		(POLAR T
  			(ANGLE T O)
  			(/ (DISTANCE T O) 2)
  		)
  	)
  	;теперь в качестве новой точки выбрана точка P
  	;будем искать точку между данной и случайной вершиной
  	(Setq O 'P)
   ))
)

   
(defun rng (/ modulus multiplier increment rand)
;;; Генерирует псевдослучайное число от 0.0000000 до 0.9999999
  (if (not seed)
	(setq seed (getvar "DATE"))
  )
  (setq
	modulus    4294967296.0 ; 65536
	multiplier 1664525      ; 25173
	increment  1            ; 13849
	seed (rem (+ (* multiplier seed) increment) modulus)
	rand (/ seed modulus)
  )
)
Радует, что программа приобретает какие-то очертания... Но:
Выдает ошибку: неверный тип аргумента: 2D/3D точка: T
Скорее всего я неправильно присваиваю ей значение, но кучу всего перепробовал, что-то не выходит нормально... Помогите, пожалуйста.
Seregarival вне форума  
 
Непрочитано 14.11.2010, 10:57
#10
TararykovDG

Программист-энтузиаст
 
Регистрация: 17.07.2009
Воронеж
Сообщений: 575


Цитата:
Сообщение от Seregarival Посмотреть сообщение
Выдает ошибку: неверный тип аргумента: 2D/3D точка: T
Скорее всего я неправильно присваиваю ей значение, но кучу всего перепробовал, что-то не выходит нормально... Помогите, пожалуйста.
Нельзя в качестве имени переменной использовать символ T - это зарезервированный символ логических операций (T - true; nil - false)
__________________
cadtools
TararykovDG вне форума  
 
Непрочитано 14.11.2010, 11:52
#11
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Точки принято обозначать как pt0 (базовая), pt1, pt2, pt3...
Цитата:
(Setq R (mapcar '(lambda (x)(fix(* x 6)))(Rng)))
Код:
[Выделить все]
(setq R (1+ (fix (* 6 (Rng)))))
Так правильно! сторона 1, 2, 3..6

Последний раз редактировалось gomer, 14.11.2010 в 12:05.
gomer вне форума  
 
Автор темы   Непрочитано 14.11.2010, 12:57
#12
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Исправил название точки и сделал как написано: (setq R (1+ (fix (* 6 (Rng))))), но все равно ошибка, только теперь чуть-чуть другая:
; ошибка: неверный тип аргумента: 2D/3D точка: nil
Сама по себе конструкция (Setq Ptt C) должна работать? То есть точка Ptt примет координаты '(200 250) ?
Seregarival вне форума  
 
Непрочитано 14.11.2010, 13:04
#13
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Где новый код?
И вообще... команда vlide и отладка в IDE, там есть все средства для этого
gomer вне форума  
 
Автор темы   Непрочитано 14.11.2010, 13:21
#14
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Код:
[Выделить все]
(DEFUN F()
  ;для начала нарисуем шестиугольник
  (Setq A '(50 150))
  (Setq B '(100 250))
  (Setq C '(200 250))
  (Setq D '(250 150))
  (Setq E '(200 50))
  (Setq F '(100 50))
  (Command "_Line" A B C D E F A "")
  ;далее внутри него нарисуем произвольную точку
  (setq O (mapcar '(lambda (x)(fix(* x 200)))(list (Rng) (Rng))))
  ;Организуем цикл для построения множества точек
  (REPEAT 100
  (
  	;выберем произвольную вершину
  	(setq R (1+ (fix (* 6 (Rng)))))
  	(if (> R 0)
  		(Setq Ptt A))
  	(if (> R 1)
  		(Setq Ptt B))
  	(if (> R 2)
  		(Setq Ptt C))
  	(if (> R 3)
  		(Setq Ptt D))
  	(if (> R 4)
  		(Setq Ptt E))
  	(if (> R 5)
        	(Setq Ptt F))
  	;поставим точку на середине отрезка между выбранной точкой и произвольной вершиной
  	(SetQ P
  		(POLAR Ptt
  			(ANGLE Ptt O)
  			(/ (DISTANCE Ptt O) 2)
  		)
  	)
  	;теперь в качестве новой точки выбрана точка P
  	;будем искать точку между данной и случайной вершиной
  	(Setq O 'P)
   ))
)

   
(defun rng (/ modulus multiplier increment rand)
;;; Генерирует псевдослучайное число от 0.0000000 до 0.9999999
  (if (not seed)
	(setq seed (getvar "DATE"))
  )
  (setq
	modulus    4294967296.0 ; 65536
	multiplier 1664525      ; 25173
	increment  1            ; 13849
	seed (rem (+ (* multiplier seed) increment) modulus)
	rand (/ seed modulus)
  )
)
Цитата:
И вообще... команда vlide и отладка в IDE, там есть все средства для этого
А можно об этом чуть подробнее?
Seregarival вне форума  
 
Непрочитано 14.11.2010, 13:49
#15
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


попробуй так
Код:
[Выделить все]
  (repeat 100
	;выберем произвольную вершину
	(setq
	  R (fix (* 5 (Rng)))
	  Ptt (nth R (list A B C D E F))
	  P ; поставим точку на середине отрезка между выбранной точкой и произвольной вершиной
	  (polar
		Ptt
		(angle ptt o)
		(/ (distance ptt o) 2)
	  )
	)
	;теперь в качестве новой точки выбрана точка P
	;будем искать точку между данной и случайной вершиной
	(setq O P)
  )
зы подробнее... описано в справке
gomer вне форума  
 
Автор темы   Непрочитано 14.11.2010, 14:02
#16
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


gomer, спасибо большое, произвольные числа вроде заработали, но отрисовки точек все равно нет, значение одной вычисленной точки он выводит в командной строке и успокаивается, добавил строку, чтобы проверить сколько точек он ищет и выяснил, что находит только первую точку, цикл не работает:

Код:
[Выделить все]
(repeat 100
	;выберем произвольную вершину
	(setq
	  R (fix (* 5 (Rng)))
	  Ptt (nth R (list A B C D E F))
	  P ; поставим точку на середине отрезка между выбранной точкой и произвольной вершиной
	  (polar
		Ptt
		(angle ptt O)
		(/ (distance ptt O) 2)
	  )
	)
	;теперь в качестве новой точки выбрана точка P
	;будем искать точку между данной и случайной вершиной
	(Command "_Line" Ptt Ptt ""); отрисовывает только одну точку
	(setq O P)
  )
Извиняюсь за стиль вывода точки, но раз не работает polar, то хоть так..
Seregarival вне форума  
 
Непрочитано 14.11.2010, 14:34
#17
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


(Command "_Line" Ptt Ptt "") рисует отрезок вырожденный в "точку" Начало и конец его совпадают... Таких "отрезков" у тебя должно быть 100 штук
И, кстати, срочно поменяй название функции, а то далеко не уедешь...
gomer вне форума  
 
Автор темы   Непрочитано 14.11.2010, 15:41
#18
Seregarival


 
Регистрация: 13.11.2010
Сообщений: 15


Поменял название и пошло дело! Но...
Блин, AutoCAD2007 запускает эту прогу, выполняет, точки появляются, но теперь начал горланить что-то про сетевые лицензии, хотя сам нигде не предлагал зарегестрировать продукт, и в настройках когда пытаюсь обновить ошибка вылезает.
В AutoCAD2010 точки не появляются... Буду разбираться с этим.
Но все же пару раз он успел запуститься в 2007, Странно(а может и не очень), но почему то рандомные вершины почти всегда выбираются 2, 3 или 4, рандом не рандомный...

В точке (50.0000, 150.0000, 0.0000) создана линия нулевой длины -пишет AutoCAD2010 и нет точки на экране! Они оказывается и работают по-разному...

Последний раз редактировалось Seregarival, 14.11.2010 в 15:52.
Seregarival вне форума  
 
Непрочитано 14.11.2010, 17:29
#19
Li6-D


 
Регистрация: 03.05.2009
Сообщений: 112


Для шестиугольника Серпинского текущая точка P должна находиться
на отрезке, соединяющего случайную вершину шестиугольника Ptt и предыдущую точку O.
При этом расстояние между вершиной и текущей точкой - 1/3 длины отрезка.
Если будет середина отрезка, то красивой фигуры не получится! Середина - это для треугольника Серпинского.
То есть надо исправить: (polar Ptt (angle Ptt O) (/ (DISTANCE Ptt O) 23)).
Чтобы из алгоритма не выпала 6-ая вершина F надо исправить: (fix (* 56 (Rng)).
Начальную точку внутри шестиугольника и число точек фрактала можно задать через getpoint и getint.
Точки фрактала можно нарисовать окружностями радиуса 0.1, а не отрезками нулевой длины.
Чтобы была видна начальная точка ее лучше нарисовать с помощью point и если она не выделяется
среди точек фрактала - изменить формат отображения точек.

Последний раз редактировалось Li6-D, 14.11.2010 в 18:36.
Li6-D вне форума  
 
Непрочитано 14.11.2010, 17:52
#20
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,515


Цитата:
Сообщение от Li6-D Посмотреть сообщение
Чтобы из алгоритма не выпала 6-ая вершина F надо исправить: (fix (* 56 (Rng)).
Хм, точно...
Вообще, шестиугольник Серпинского как фрактал строится рекурсивно и мне непонятно зачем здесь rng и где собственно рекурсия

Последний раз редактировалось gomer, 14.11.2010 в 18:04.
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > LISP > Фракталы в AutoLISP



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
передача данных из AutoLisp в Excel Victorovich LISP 2 03.12.2011 22:28
Реализация алгоритма шифрования AES средствами AutoLisp gomer LISP 20 09.09.2010 11:55
Как отладить нейтив и менеджед код в COM объекте который используется из AutoLISP? lexluther LISP 1 12.08.2009 08:37
Как выделить примитивы в AutoLISP? RastaMANNN LISP 3 10.06.2008 00:37
Как из Delphi запустить программу на AutoLISP Valery LISP 1 23.09.2005 20:51