публикую программу zipsfx

Доброго времени! публикую свою программу zipsfx-cpp

Преамбула

Была у меня такая идея создавать на лету SFX (Самораспаковывающийся архив) файлы средствами JAVA

JAVA из коробки поддерживает работу с zip архивами, при том хотелось чтобы были соблюдены следующие условия
  • Создание sfx архива должно работать из любой ОС
  • Создание sfx архива должно быть реализовано в пределах JAVA
Облазив тырнет (где-то 2011 - 2012) я не нашел подходящего решения, из возможных решений было использование 7z, все хорошо, есть SDK, есть "модуль" SFX, кроме одного, оно работает с только 7z архивами (так было 2012)

Тогда было решено написать свой

О программе

Суть использования программы сводится к нескольким шагам
  1. Создать каким либо образом zip архив, тем же 7zip или средствами JAVA.
    Назовем этот файл data.zip или еще как либо.
  2. Создать текстовый файл с параметрами распаковки (куда распаковывать, что потом сделать).
    Назовем этот файл options.txt или еще как либо.
  3. Склеить файлы install.exe = zipsfx + options.txt + data.zip
Вот пример работающей версии:

Шаг 1 - создание архива

Файл data.zip
Содержит два файла:
  1. launcher.bat
  2. data/launcher-2.bat
data/launcher-2.bat в себе содержит следующий код:
@echo off
echo current dir "%CD%"
pause

Шаг 2 - создание параметров

Файл options.txt
OPTIONS BEGIN {
# Hello text
hello = HELLO4 Test arguments

# Show hello text
showHello = false

# Show log progress
showLog = false

# Delete files on exit
deleteFiles = true

# Run after extract
run = cmd /C launcher-2.bat $args

workDir = $dir\data

# return exit code from run
return = true

# true - use temp dir; false - use current dir
useTemp = true
} OPTIONS END


run = cmd /C launcher-2.bat $args - указывает, что после распаковки, необходимо выполнить команду запуска bat файла

workDir = $dir\data - указывает, что выполнить надо команду, в под каталоге data, относительно распакованного каталога

deleteFiles = true - указывает, что по завершению, надо удалить фалы

Шаг 3 - склейка фалов

Вот так склеиваем файлы (в командной строке)
copy /b zipsfx + options.txt + data.zip test.exe

Выполнение того что получилось



Дистрибутив программы

Дистрибутив программы, а так же исходный код (лицензия MIT) расположен на сайте https://github.com/gochaorg/zipsfx-cpp

Дистрибутив программы - это всего один файл (zipsfx), который не требует какой либо установки, он и является тем самым самораспаковывающийся архив, точнее заголовок exe файла.

Более подробное описание расположено на сайте github

Перевод Bashrc

Надоело смотреть на скучные комментарии на англицком в файле .bashrc
Как известно этот файл отвечает за настройку командной строки (bash) в linux/freebsd и т.д.
#!/bin/bash
# ~/.bashrc: выполняется программой bash для Non-login оболочки (да и для оной тоже)
# см. /usr/share/doc/bash/examples/startup-files (в пакете документации bash-doc)
# для примеров

# Если не интерактино, то ничего не делать
case $- in
    *i*) ;;
      *) return;;
esac

# Не выводить в историю повторяющиеся строки
# или строки начинающиеся с пробела
# см. bash(1) для дополнительных опций
HISTCONTROL=ignoreboth

# добавить в файл истории, не перезаписать его
shopt -s histappend

# Длина файла истории см. bash(1)
HISTSIZE=1000
HISTFILESIZE=2000

# Проверить размер окна после каждой команды и при необходимости, 
# Обновить значения строк (LINES) и столбцов (COLUMNS).
shopt -s checkwinsize

# Если установлено, шаблон "**" используется в контексте расширения путь будет 
# Соответствовать всем файлам и ноль или более каталогов и подкаталогов. 
#shopt -s globstar

# Сделать менее более дружественным для входных файлов нетекстовых см. lesspipe (1) 
#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)"

# Установить переменную идентифицирующую работу в окружении chroot (используется в следующем приглашении)
if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then
    debian_chroot=$(cat /etc/debian_chroot)
fi

# Установить подсказку цветной по возможности 
# Зависит от переменной TERM
case "$TERM" in
    xterm-color) color_prompt=yes;;
esac

# Раскомментируйте для цветной подсказки, если терминал имеет эту возможность;
# По умолчанию отключено, чтобы не отвлекать пользователя от фокуса внимания в окне терминала 
# Должно быть на выходе команд, а не вводимой строке
#force_color_prompt=yes

if [ -n "$force_color_prompt" ]; then
    if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then

# У нас есть поддержка цвета; предполагаю, что это соответствует ECMA-48 
# (ISO/IEC-6429). (Отсутствие такой поддержки крайне редко, 
#  и пусть будет так. Как правило поддерживается SETF, а не setaf.)
color_prompt=yes
    else
color_prompt=
    fi
fi

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else
    PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ '
fi
unset color_prompt force_color_prompt

# Если это Xterm задать заголовок так: user@host:dir
case "$TERM" in
xterm*|rxvt*)
    PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1"
    ;;
*)
    ;;
esac

# Включить поддержку цвета для ls, а также добавить удобные псевдонимы
if [ -x /usr/bin/dircolors ]; then
    test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)"
    alias ls='ls --color=auto'
    alias dir='dir --color=auto'
    alias vdir='vdir --color=auto'

    alias grep='grep --color=auto'
    alias fgrep='fgrep --color=auto'
    alias egrep='egrep --color=auto'
fi

# Еще несколько ls псевдонимов
alias ll='ls -l'
alias la='ls -A'
alias l='ls -CF'

# Вы можете поместить все ваши дополнения в отдельный файл, как 
# ~/.bash_aliases вместо добавления их здесь непосредственно. 
# см. /usr/share/doc/bash-doc/examples в пакете документации bash-doc
if [ -f ~/.bash_aliases ]; then
    . ~/.bash_aliases
fi

# Включить программируемые функции завершения (дополнительно включать не нужно,
# т.к. уже включено в  /etc/bash.bashrc , /etc/profile и /etc/bash.bashrc
if ! shopt -oq posix; then
  if [ -f /usr/share/bash-completion/bash_completion ]; then
    . /usr/share/bash-completion/bash_completion
  elif [ -f /etc/bash_completion ]; then
    . /etc/bash_completion
  fi
fi

###############################################################################
# Добавлено мной

# Переопределение цветной подсказки в таком виде:
#   ЧЧ.ММ.СС:user@host:dir
#   > тут_курсор_ввода
PS1='\[\033[02;32m\]\D{%H.%M.%S}\033[00m:\033[0;34m\u@\h\[\033[00m\]:\w\n> '
export PS1

# Добавление путей поиска
PATH="~/.bin:~/bin:$PATH"
export PATH

Измерение отрезков общего положения

В предыдущей части я рассмотрел как построить отрезки в перспективе, были рассмотрены только частные случаи - горизонтальные, вертикальные и уходящие в глубь отрезки линий.

Теперь разберемся как измерить отрезок который расположен в горизонтальной плоскости, под не известным углом и как нарисовать еще один отрезок такой же длины в перспективе.

И так нам дано: перспектива отрезка AB и нам необходимо продлить этот отрезок в глубь, на такую же длину что бы получился отрезок BC равный по длине AB.


Алгоритм

1. Через точки A и B проведем линию до пересечения с линией горизонта hh1, точку пересечения отметим буквой F


2. Возьмем циркуль и проведем дугу, где центр будет точка - F, радиус дуги будет - отрезок FSk, начало дуги в точке Sk, а ее конец на линии горизонта в точке M.

Наша точка M - это специальная точка, ее название масштабная точка. Используя ее мы узнаем размеры отрезка AB

3. Через масштабную точку M проведем две линии, через точки A и B, до основания картины. На основании картины отметим соот. точки Ao и Bo.

Реальный размер отрезка AB мы можем получить взяв линейку и померив ей отрезок AoBo


4. Теперь отмерим на основании отрезок BoCo такой же по длине как и AoBo, и проведем линию из точки Co, до точки M.
Линия пересечет прямую AB в точке C.
Вот так мы и построили нужный нас отрезок BC.

Перспективные масштабы

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

Напрашивается вопрос - как правильно отобразить размеры объекта в перспективе.
Сначала рассмотрим три частных случая:
  • Масштаб ширины - сокращение отрезков расположенных параллельно основанию картины
  • Масштаб высоты - сокращение вертикальных отрезков
  • Масштаб глубины - сокращение отрезков направленных в глубь картины, т.е. отрезки направленные в главную точку схода P

Масштаб ширины

Допустим у нас есть уже горизонтальный отрезок AB в перспективе, и есть еще точка С лежащая немного дальше этого отрезка. Необходимо построить перспективу горизонтального отрезка CD такой же длины как и AB


Алгоритм

1. Из точки A через точку C проведем до горизонта линию, точку пересечения обозначим буквой F
2. Из точки F до точки B проведем вторую линию


3. Проводим горизонтальную линию из точки C до пересечения с прямой FB, точка пересечения - будет искомой точкой D



Масштаб высоты

Масштаб высоты выполняется аналогично масштабу ширины



Масштаб глубины

Теперь у нас немного другая ситуация, у нас есть отрезок AB который направлен строго в глубь, точка B пересекает основание картины.
Нам необходимо построить перспективу отрезка AB.



Алгоритм

1. По скольку отрезок AB расположен перпендикулярно картинной плоскости, то точка схода прямой AB будет P
Проведем соот. линию BP - это будет перспектива прямой AB, но не отрезка AB, на еще необходимо найти точку A на этой прямой.

2. Отложим от точки B вправо отрезок BC нужной длинны - такой же как и AB.

3. Соединим прямой точки AC

Теперь мы имеем прямую AC расположенную под 45 градусов, в соответствии о точках схода, эта прямая будет иметь точку схода D

4. Нарисуем перспективу прямой AC, проведем из точки C в точку D прямую, точка пересечения прямых CD и BP - будет искомая точка A.



Обратная задача

Теперь рассмотрим обратную задачу
У нас есть уже нарисованная перспектива отрезка расположенного в глубь. В дополнение у нас дистанционные точки выходят за границы листа

Нам необходимо узнать размеры отрезка AB
Вот ниже картинка этого случая
 

Алгоритм

1. Давай уменьшим величину D в два раза и отметим ее на горизонте как точка D/2.
2. Проведем перспективу прямой AB, из точки A, через B и до точки P проведем прямую
3. Теперь из точки D/2 проведем две прямые через точки A и B до пересечения с основанием картины, 
4. Мы получили отрезок AoBo размером 5,6 см, по скольку он получен с использованием точки D/2, то реальный размер отрезка AB будет больше в два раза 5,6 * 2 = 11,2 см.

Возможно использовать не только точки D/2, но и например D/4 и т.д. соответственно реальные размеры необходимо будет увеличивать в соответствующую кратность. 

Пример построения перспективы квадрата
В нашем примере точка D находится за пределами листа, по этому мы будем использовать точку D/2
Изначально у нас есть только точка P и отрезок 1-2 и мы хотим построить квадрат размером с этот отрезок.

1. Проведем из точек 1 и 2 две прямых в точку P
2. Возьмем отрезок 1-2 и разделим поровну получим два равных отрезка 1-5 и 5-2, при использовании точки D/2 отрезок 5-2 будет соответствовать боковой стороне квадрата.
3. Из точки 5 проведем прямую до точки D/2, она пересечет прямую 2-P в точке 3
4. Из точки 3 проведем горизонтальную прямую до пересечения с прямой 1-P, в точке 4

Вот и все мы имеем перспективу квадрата с углами в точках 1,2,3,4

Перспектива паркета

Так же как и для построения перспективы точки, нам понадобятся следующее:
Рисунок будущего паркета у меня такой:

По скольку все линии паркета располагаются под 45 градусов, то соответ. эти линии в перспективе будут сходится в две точки, D и D1 (см. Точки схода)

Как я строил перспективу паркета
1. Расстояние Sk P - взял с потолка, но по больше
2. Высоту горизонта взял по меньше, чем расстояние SkP
3. Провел линию горизонта
4. На линии горизонта отметил центральную точку P
5. Дистанционные точки D,D1 (они соответ. точкам схода 45 градусов) отметил на линии горизонта, на расстояние равном SkP от точки P.
6. Параллельно ниже провел линию основания картины на расстоянии соот. высоте горизонта
7. Ниже линии основания нарисовал паркет, так если смотреть на него сверху

Вот что у меня на этом этапе соответственно получилось


8. Далее я пунктиром провел линии из основания картины в точки схода


9. Последним шагом я по намеченным пунктирным линиям закрасил перспективные прямоугольники сверяясь с рисунком, и вот ниже вы можете видеть результат

Перспектива точки

Для построения перспективы точки нам понадобится
В моем примере:
  • лист бумаги составляет 12 см по горизонтали и 19 см по вертикали
  • Расстояние SP равно 7 см (О точки зрения S до главной точки картины P)
  • Высота горизонта от основания картины - 4 см

Алгоритм построения

1) На предметной плоскости H" я произвольно отметил точку A", предлагаю вам отметить эту точку по ближе к краю листа


2) От точки A" к основанию картины я провел перпендикуляр и отметил точку пересечения Ao - основания картины (OO1) и проведенного перпендикуляра

3) По скольку все перпендикулярные линии (перпендикулярные к картине) сходятся в главной точке P, я провел соот. линию от точки Ao до точки P



4) Из точки S до точки A" я провел прямую линию, и она пересекла предыдущую перспективную линию Ao P, точка пересечения - это и есть искомая перспектива точки A". Я ее отметил буквой A



Построение прямоугольника 

Зная алгоритм, давайте построим перспективу прямоугольника лежащего на плоскости H"
У меня получилось вот это:



К предыдущему рисунку я добавил три точки B", C" и D" и по антологии построил их перспективу

Точки схода

Точка схода - это такая точка на картине где сходятся вместе параллельные прямые, т.е. параллельные прямые они в пространстве не сходятся, а на картине сходятся. Вот на пример железно дорожные линии
Рассмотрим подробнее. Я в 3D программе нарисовал три пары параллельных прямых: белые, синие и красные.
  • Белые расположены перпендикулярно картине
  • Синие повернуты на 20 градусов влево относительно белых
  • Красные повернуты на 20 градусов вправо и на 5 градусов вверх 
И наблюдаем следующие закономерности
  • Белые линии сходятся на горизонте в точке главной точке P
  • Синие линии сходятся тоже на горизонте, но немного левее точки P, в точке F
  • Красные линии сходятся во первых правее точки P, и выше линии горизонта, в точке W
Обозначения F, V, W ... - это точки схода для произвольных прямых
согласно учебнику Соловьева
Обобщая наблюдения можно заявить следующее:
Для двух и более параллельных прямых на картине будет одна общая точка схода

Частные случаи

Можно выделить несколько частных случаев для прямых. Их три:
  • Вертикальные прямые, они параллельны картине и ориентированы вертикально. Для таких двух или более параллельных прямых нет общих точек схода.
  • Горизонтальные прямые, они тоже параллельные картине и ориентированы горизонтально. Для двух таких параллельных прямых, так же нет общих точек схода.
  • Прямые перпендикулярные картине - для них всегда будет одна общая точка схода - главная точка P 

Точки схода на совмещенной плоскости

Теперь рассмотрим случай как выбирать точки схода для линий лежащих (либо параллельных) на предметной плоскости H.
смотрите также понятие Совмещенна предметна плоскость
Построим две прямые, одна под 45 градусов к картине, другая под 60 градусов:

1) Соответственно для прямой под 45 градусов найдем точку схода D на горизонте, для этого из точки Sk проведем прямую под углом 45 градусов в линии горизонта, до пересечения с ним.
D - это специальная точка, ее название дистанционная. Точки схода расположенные под 45 градусов называются дистанционными и обозначаются буквами D и D1.
2) А для прямой в 60 градусов, сделаем аналогичное действие, эту точку обозначим буквой F
А теперь нарисуем перспективу параллельных прямых 45 и 60 градусов
На рисунке пунктиром у нас обозначены прямые под 60 градусов, а сплошной линией прямые под 45 градусов