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

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

Кубик Рубика

Ответ
Поиск в этой теме
Непрочитано 05.05.2014, 10:59 1 | #1
Кубик Рубика
Дима_
 
Продуман
 
Питер
Регистрация: 22.02.2007
Сообщений: 2,840

На майских пришло вдохновение и по мотивам змеи решил создать продолжение. Скомпилированные версии под 2010 (подозреваю, что будут работать с 2008 по 2010) и 2014 (видимо с 2013 по 2015). Запускать командой KR и смотреть в начало координат.
Код:
[Выделить все]
open System
open System.Drawing 
open System.Windows.Forms                 
open Autodesk.AutoCAD.ApplicationServices 
open Autodesk.AutoCAD.Runtime
open Autodesk.AutoCAD.DatabaseServices
open Autodesk.AutoCAD.EditorInput
open Autodesk.AutoCAD.Geometry
open Autodesk.AutoCAD.Colors
                           
let Init()= //Инициализация активных имен
  let doc=Application.DocumentManager.MdiActiveDocument
  doc,doc.Editor,doc.Database,doc.TransactionManager.StartTransaction
let MakeBox l s h (pt:Point3d) color visible= //создает "ящик" размерами l,s,h, в заданной точке с цветом и видиостью
    let box=new Solid3d(Visible=visible)
    box.CreateBox(l,s,h)
    box.Color<-color
    box.TransformBy(Matrix3d.Displacement(pt.GetAsVector()))
    box
let AppendEnts (tr:Transaction) (block:BlockTableRecord) ents= // сохраняет список примитовов в блоке через заданную транзакцию
    let ids=ents|>List.map (fun ent->block.AppendEntity ent)
    ents|>List.iter (fun ent->tr.AddNewlyCreatedDBObject(ent,true))
    ids
let Arr3D (ent:Entity) row col hi delta= // трехмерный массив элементов
  {1..col}|>Seq.map (fun c->{1..row}|>Seq.map (fun r->{1..hi}|>Seq.map (fun h->ent.GetTransformedCopy(Matrix3d.Displacement(new Vector3d(float(c)*delta,float(r)*delta,float(h)*delta))))))
           |>Seq.concat|>Seq.concat|>Seq.toList
let GetObjects (tr:Transaction) lstId= //получает список объектов по транзакции и списку ID
    lstId|>List.map (fun id->tr.GetObject(id,OpenMode.ForWrite))
let IsIntersectSolid3d (ent1:Solid3d) (ent2:Solid3d)= //предикат на пересечение трехмерных тел
  let vol=ent1.MassProperties.Volume+ent2.MassProperties.Volume
  let cl=ent1.Clone():?>Solid3d
  cl.BooleanOperation(BooleanOperationType.BoolUnite,(ent2.Clone():?>Solid3d))
  let ret=abs(cl.MassProperties.Volume-vol)>0.01
  cl.Dispose()
  ret
let GetIntersection ent = // отфильтровываетт список 3dSolid'ы на только пересекающие Ent
  Seq.filter (IsIntersectSolid3d ent)
let OptimizeRotations lst= // оптимизирует движения кубика
    let rec fn=function
      |ret,(os,d)::(osx,dx)::tail
      |(os,d)::ret,(osx,dx)::tail 
      |(os,d)::(osx,dx)::ret,tail when os=osx&&d<>dx->fn(ret,tail) // убирает все взаимообратные (туда-сюда)
      |ret,[]->ret|>List.rev
      |ret,(os,d)::b::c::tail when (os,d)=b&&b=c->fn((os,d|>not)::ret,tail) // вместо трех однонаправленных по 1 оси - 1 в другую сторону
      |ret,a::b->fn(a::ret,b)
    fn([],lst)

[<CommandMethod "KR">]
let KubikCad()=
  let doc,ed,db,trf=Init() // инициализация
  use tr=trf() // транзакция
  let model=tr.GetObject((tr.GetObject(db.BlockTableId,OpenMode.ForRead):?>BlockTable).[BlockTableRecord.ModelSpace],
                         OpenMode.ForWrite):?>BlockTableRecord // пространство модели
  let KubikId= // список Id сегментов кубика
    let box=MakeBox 19.8 19.8 19.8 (new Point3d(0.0,0.0,0.0)) (Color.FromRgb(0uy,0uy,0uy)) true // сегмент
    let boxes=Arr3D box 3 3 3 20.0|>List.map (fun x->x:?>Solid3d) //сегменты
    let red=MakeBox 19.8 19.8 0.4 (new Point3d(0.0,0.0,50.0)) (Color.FromRgb(255uy,0uy,0uy)) true //красная наклейка
    let green=MakeBox 19.8 19.8 0.4 (new Point3d(0.0,0.0,-10.0)) (Color.FromRgb(0uy,255uy,0uy)) true //зеленая
    let blue=MakeBox 19.8 0.4 19.8 (new Point3d(0.0,50.0,0.0)) (Color.FromRgb(0uy,0uy,255uy)) true //голубая
    let white=MakeBox 19.8 0.4 19.8 (new Point3d(0.0,-10.0,0.0)) (Color.FromRgb(255uy,255uy,255uy)) true //белая
    let gray=MakeBox 0.4 19.8 19.8 (new Point3d(-10.0,0.0,0.0)) (Color.FromRgb(127uy,127uy,127uy)) true // серая
    let colors=(Arr3D red 3 3 1 20.0)@(Arr3D green 3 3 1 20.0)@(Arr3D blue 1 3 3 20.0)@
                 (Arr3D white 1 3 3 20.0)@(Arr3D gray 3 1 3 20.0)|>List.map (fun x->x:?>Solid3d) // список из всех наклеек
    // наклеивает все цвета на "свои" кубики
    boxes|>Seq.iter (fun b->GetIntersection b colors|>Seq.iter (fun x->b.BooleanOperation(BooleanOperationType.BoolUnite,x)))
    boxes|>AppendEnts tr model // добавляет в модель
  let OsiId= // создает 3 невидимые оси вращения XYZ
    let osi=[new Line(Point3d(30.0,40.0,40.0),Point3d(50.0,40.0,40.0),Visible=false)
             new Line(Point3d(40.0,30.0,40.0),Point3d(40.0,50.0,40.0),Visible=false)
             new Line(Point3d(40.0,40.0,30.0),Point3d(40.0,40.0,50.0),Visible=false)]
    osi|>AppendEnts tr model //  в модель
  let MarkerId= // 9 плоскостей определения кубиков на текущей оси
      (Arr3D (MakeBox 0.1 30.0 30.0 (Point3d(0.0,20.0,20.0)) (Color.FromRgb(0uy,0uy,0uy)) false) 1 3 1 20.0)@
      (Arr3D (MakeBox 30.0 0.1 30.0 (Point3d(20.0,0.0,20.0)) (Color.FromRgb(0uy,0uy,0uy)) false) 3 1 1 20.0)@
      (Arr3D (MakeBox 30.0 30.0 0.1 (Point3d(20.0,20.0,0.0)) (Color.FromRgb(0uy,0uy,0uy)) false) 1 1 3 20.0)
        |>AppendEnts tr model // в модель
  tr.Commit() // закрывает транзакцию
  //поворачивает кубики из списка вокруг оси лежащие на заданной плоскости на заданный угол
  let RotateKR (kubik:Solid3d list) (osi:Line list) (mark:Solid3d list) i ang =
    let pt=osi.[i/3].StartPoint //определяет матрицу поворота
    let mtr=Matrix3d.Rotation(ang/10.0,new Vector3d(Array.map2 (-) (pt.ToArray()) (osi.[i/3].EndPoint.ToArray())),pt)
    let rotations=kubik|>GetIntersection mark.[i]|>Seq.map (fun x->x.ObjectId)|>Seq.toList
    {1..10}|>Seq.iter (fun _ ->use tr=trf() // производит плавный 10-ти шаговый поворот в отдельных транзакциях
                               rotations|>GetObjects tr|>Seq.iter (fun x->(x:?>Entity).TransformBy(mtr))
                               tr.Commit()
                               ed.UpdateScreen()) // обновляя экран на каждом
  let RotateThis os direction= //поворот на 90 соотв. оси кубика в выбранном направлении
    use tr=trf()
    use ld=doc.LockDocument()
    let a,b,c=(GetObjects tr KubikId|>List.map (fun x->x:?>Solid3d)), // определяет поворачиваемые сегменты
              (GetObjects tr OsiId|>List.map (fun x->x:?>Line)), // оси поворота
              (GetObjects tr MarkerId|>List.map (fun x->x:?>Solid3d)) // и оси выбора
    tr.Commit()
    RotateKR a b c os (Math.PI/2.0*(direction|>function true->1.0|false-> -1.0)) // поворот
  let form=new Form(Text="KubicCAD",TopMost=true,AutoSize=true, // окно GUI'я
                    SizeGripStyle=SizeGripStyle.Hide,
                    Size=Size(0,0),
                    MaximizeBox=false,
                    MinimizeBox=false)
  let UndoButton=new Button(Parent=form,AutoSize=true,Width=0,Text="O",Tag=([]:(int*bool) list)) // кнопка возрата кубика в исходное
  UndoButton.Click.Add(fun _ ->(UndoButton.Tag:?>(int*bool) list) // берет список поворотов
                                  |>OptimizeRotations // оптимизирует
                                  |>Seq.iter (fun (i,d)->RotateThis i d) // поворачивает в иходные
                               UndoButton.Tag<-([]:(int*bool) list)) // обнуляет список
  let MixButton=new Button(Parent=form,AutoSize=true,Width=0,Text="X",Top=UndoButton.Bottom)//кнопка перемешивания
  let rnd=new Random(DateTime.Now.Millisecond)
  MixButton.Click.Add(fun _ ->{0..rnd.Next(10,15)}|>Seq.iter (fun _ ->let r=rnd.Next(9)
                                                                      RotateThis r true
                                                                      UndoButton.Tag<-(r,false)::(UndoButton.Tag:?>(int*bool) list)))
  //создает конпки формы
  let buttons={0..9}|>Seq.map (fun x->let b=new Button(Parent=form,AutoSize=true,Width=0,Text="X")
                                      let bx=new Button(Parent=form,AutoSize=true,Width=0,Text="X")
                                      b.Click.Add(fun _ ->RotateThis x true // и присваивает им функции поворота вокруг осей
                                                          UndoButton.Tag<-(x,false)::(UndoButton.Tag:?>(int*bool) list)) // и записи "отката"
                                      bx.Click.Add(fun _ ->RotateThis x false
                                                           UndoButton.Tag<-(x,true)::(UndoButton.Tag:?>(int*bool) list))
                                      [b;bx])
                    |>Seq.concat
  buttons|>Seq.iter2 (fun (x,y,label) b->b.Left<-x*b.Width // расставляет кнопки по форме и рисует значки
                                         b.Top<-y*b.Height
                                         b.Text<-label)
                     [2,0,"^";2,1,"v";3,0,"^";3,1,"v";4,0,"^";4,1,"v"
                      0,5,"<";1,5,">";0,4,"<";1,4,">";0,3,"<";1,3,">"
                      3,2,"]";2,3,"[";4,3,"]";3,4,"[";5,4,"]";4,5,"["]
  form.MaximumSize<-form.Size // фиксирует размеры формы
  doc.BeginDocumentClose.Add(fun _ ->form.Close()) // закрывает форму при закрытии документа
  form.Show() //показывает форму

Изображения
Тип файла: jpg Снимок.JPG (45.0 Кб, 1979 просмотров)

Вложения
Тип файла: zip clip.zip (497.0 Кб, 223 просмотров)
Тип файла: zip kr.zip (720.2 Кб, 241 просмотров)

__________________
Когда в руках молоток все вокруг кажется гвоздями.

Последний раз редактировалось Дима_, 07.05.2014 в 00:25.
Просмотров: 8191
 
Непрочитано 06.05.2014, 18:52
#2
Do$

AutoCAD/Civil3D LISP/C#
 
Регистрация: 15.08.2008
Санкт-Петербург
Сообщений: 1,702
Отправить сообщение для Do$ с помощью Skype™


Вах! Шайтанама
С управлением тяжело разобраться, особенно если по хитрому СК развернуть.
Кнопки "перемешать" не хватает
__________________
Толковый выбор приходит с опытом, а к нему приводит выбор бестолковый. (The Mechanic)
Do$ вне форума  
 
Автор темы   Непрочитано 06.05.2014, 21:35
#3
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Цитата:
Сообщение от Do$ Посмотреть сообщение
С управлением тяжело разобраться, особенно если по хитрому СК развернуть.
Я тоже голову сломал - как сделать чтоб "юзабельно" было - пробовал если по кубику щелкать - ИХМО еще хуже - будет интересная идея по варианту управления - не молчим.

----- добавлено через ~3 ч. -----
Цитата:
Сообщение от Do$ Посмотреть сообщение
Кнопки "перемешать" не хватает
Согласен - перезалил #1.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 07.05.2014, 10:10
#4
Nata1

Инженер
 
Регистрация: 10.11.2008
Владимирская обл., пос. Вольгинский
Сообщений: 147


Как сохранить код, чтобы загрузить в автокад? KR.LSP?
__________________
AutoCAD 2014
Nata1 вне форума  
 
Автор темы   Непрочитано 07.05.2014, 10:45
1 | #5
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Цитата:
Сообщение от Nata1 Посмотреть сообщение
Как сохранить код, чтобы загрузить в автокад?
Это F# - его надо скомпилировать в dll, который заргузить, например командой netload. Скомпилированные версии уже лежат в архиве kr.zip.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 25.07.2014, 07:41
#6
Aimod


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


Цитата:
Сообщение от Дима_ Посмотреть сообщение
будет интересная идея по варианту управления - не молчим
Использовать сочетания цифр цифрового блока и клавиш-стрелок. Подсветить всегда недвижимую квадратную рамку активной стороны.
Цифровой блок визуально выглядит как верхний, средний и нижний ряд стороны кубика. Если зажать 7-ку и стрелку влево - верхний ряд повернется влево один раз.
Заранее простите, что лезу не в свое дело.
Aimod вне форума  
 
Непрочитано 11.08.2015, 15:02
#7
Avodo


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


Загрузил kr2014.dll в Акад 2014 (х64). Не работает. Написал очень много чего про FrameWork и послал на сайт майкрософта))
Avodo вне форума  
 
Автор темы   Непрочитано 11.08.2015, 23:09
#8
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Хм. действительно не работает - странно - в моем архиве вроде тот-же файл - грузиться - видимо чего-то накомпилировал не-то.
Перезалью сюда 2014 версию.
Вложения
Тип файла: zip kr2014.zip (414.6 Кб, 35 просмотров)
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 12.08.2015, 10:06
#9
Avodo


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


Файл из #8 на виндовс х64 не заработал. Но дома на х86 и 2012 акаде работает версия kr2010.dll
Посмотрел, поигрался, очень прикольно. Спасибо!
Avodo вне форума  
 
Автор темы   Непрочитано 12.08.2015, 22:45
#10
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


А - я понял - с библиотеками в обоих архивах все в порядке - причина в этом.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 07.09.2015, 11:09
#11
DEM

YngIngKllr
 
Регистрация: 29.03.2005
СПб
Сообщений: 12,968


Цитата:
Сообщение от PeterNovik Посмотреть сообщение
Ну, чего, неплоха идея. Поиграться можно, вот бы вы его еще довели эту работу до платформ мобильных устройств - с руками вырвут
Их вполне достаточно и для Android.
__________________
Работаю за еду.
Working for food.
Für Essen arbeiten.
العمل من أجل الغذاء
Працую за їжу.
DEM вне форума  
 
Автор темы   Непрочитано 07.09.2015, 23:53
#12
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Видимо от поста только цитата и осталась?
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 08.09.2015, 00:44
#13
Admin
Administrator


 
Регистрация: 21.08.2003
Сообщений: 4,407


Offtop:
Цитата:
Сообщение от Дима_ Посмотреть сообщение
Видимо от поста только цитата и осталась?
это спамер, посты набивал
Admin вне форума  
 
Непрочитано 08.09.2015, 01:00
#14
Nike

Шаражпроектхалтурмонтаж
 
Регистрация: 29.10.2004
Талды-Париж
Сообщений: 5,989


Дима_, бездельник!
Nike вне форума  
 
Автор темы   Непрочитано 08.09.2015, 07:57
#15
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Ну как сказать - я по 8 часов в день программирую (ну или на бумажках "формулы" рисую) будет хорошая идея так напишу и выложу.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 08.09.2015, 08:30
#16
small

проектирование
 
Регистрация: 08.10.2007
Новокузнецк
Сообщений: 17


доброго времени суток.
вещь классная.
а можно для NanoCAD скомпилировать и Змейку и кубик рубик.
Заранее благодарны.
С уважением конструкторское бюро.
__________________
Никогда не поздно спросить себя: делом ли я занимаюсь, или пустяками

Антон Павлович Чехов
small вне форума  
 
Автор темы   Непрочитано 08.09.2015, 09:07
#17
Дима_

Продуман
 
Регистрация: 22.02.2007
Питер
Сообщений: 2,840


Можно - компилируйте нанокада у меня нет.
__________________
Когда в руках молоток все вокруг кажется гвоздями.
Дима_ вне форума  
 
Непрочитано 08.09.2015, 09:17
#18
small

проектирование
 
Регистрация: 08.10.2007
Новокузнецк
Сообщений: 17


Цитата:
Сообщение от Дима_ Посмотреть сообщение
Можно - компилируйте нанокада у меня нет.
а как?
__________________
Никогда не поздно спросить себя: делом ли я занимаюсь, или пустяками

Антон Павлович Чехов
small вне форума  
 
Непрочитано 08.09.2015, 09:29
#19
Сергей Юрьевич

Строительство гидротехнических сооружений
 
Регистрация: 01.08.2012
Москва
Сообщений: 8,639


Цитата:
Сообщение от small Посмотреть сообщение
доброго времени суток.
вещь классная.
а можно для NanoCAD скомпилировать и Змейку и кубик рубик.
Заранее благодарны.
С уважением конструкторское бюро.
Offtop: в Новокузнецке совсем заскучали в конструкторском бюро?
__________________
Профессионал - это тот, кто владеет двумя знаниями: как можно делать и как категорически нельзя!
Сергей Юрьевич вне форума  
 
Непрочитано 08.09.2015, 09:47
#20
small

проектирование
 
Регистрация: 08.10.2007
Новокузнецк
Сообщений: 17


Цитата:
Сообщение от Сергей Юрьевич Посмотреть сообщение
Offtop: в Новокузнецке совсем заскучали в конструкторском бюро?
Есть немного
__________________
Никогда не поздно спросить себя: делом ли я занимаюсь, или пустяками

Антон Павлович Чехов
small вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > Готовые программы > Кубик Рубика

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Почему в редакторе блока нельзя использовать навигационный кубик? Павлюкас AutoCAD 9 27.08.2011 01:18