openFrameworks vs Processing



VS

Сайты:
OF: http://www.openframeworks.cc
P: http://processing.org

Лицензия:
OF: MIT (используемые библиотеки, имеют собственные лицензии)
P: GPL and LGPL

Версия:
OF: 0.061
P: 1.2.1

Wiki:
OF: http://en.wikipedia.org/wiki/OpenFrameworks
P: http://en.wikipedia.org/wiki/Processing_(programming_language)
http://ru.wikipedia.org/wiki/Processing

Документация:
OF: http://www.openframeworks.cc/documentation
P: http://processing.org/reference/

Попробуем портировать скетч Processing-а в программу для OpenFrameworks.
Возьмём скетч Chain.pde (Topics — Simulate)

Цепь. Один массивный объект (окружность) прикрепляется к позиции указателя мышки, а второй объект прикрепляется к первому. На оба объекта действует сила гравитации, которая тянет их вниз.

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

Вот как это выглядит:

А вот код Processing-а:

/**
 * Chain. 
 * 
 * One mass is attached to the mouse position and the other 
 * is attached the position of the other mass. The gravity
 * in the environment pulls down on both. 
 */


Spring2D s1, s2;

float gravity = 6.0;
float mass = 2.0;

void setup() 
{
  size(200, 200);
  smooth();
  fill(0);
  // Inputs: x, y, mass, gravity
  s1 = new Spring2D(0.0, width/2, mass, gravity);
  s2 = new Spring2D(0.0, width/2, mass, gravity);
}

void draw() 
{
  background(204);
  s1.update(mouseX, mouseY);
  s1.display(mouseX, mouseY);
  s2.update(s1.x, s1.y);
  s2.display(s1.x, s1.y);
}

class Spring2D {
  float vx, vy; // The x- and y-axis velocities
  float x, y; // The x- and y-coordinates
  float gravity;
  float mass;
  float radius = 20;
  float stiffness = 0.2;
  float damping = 0.7;
  
  Spring2D(float xpos, float ypos, float m, float g) {
    x = xpos;
    y = ypos;
    mass = m;
    gravity = g;
  }
  
  void update(float targetX, float targetY) {
    float forceX = (targetX - x) * stiffness;
    float ax = forceX / mass;
    vx = damping * (vx + ax);
    x += vx;
    float forceY = (targetY - y) * stiffness;
    forceY += gravity;
    float ay = forceY / mass;
    vy = damping * (vy + ay);
    y += vy;
  }
  
  void display(float nx, float ny) {
    noStroke();
    ellipse(x, y, radius*2, radius*2);
    stroke(255);
    line(x, y, nx, ny);
  }
} 

Попробуем портировать его на OpenFrameworks.
В директории examples создаём новую папку, которую назовём myofChain.
Копируем туда содержимое директории emptyExample, переименовываем файлы проекта и вносим в них требуемые изменения (этот шаг подробно описан во вводной статье про OpenFrameworks)

Первым делом нужно создать файлы Spring.h и Spring.cpp
— в них будет храниться класс Spring2D:

Spring.h:

#ifndef _SPRING_H_
#define _SPRING_H_

//
// openFrameworks vs Processing
// 
// Chain.pde
//

#include "ofMain.h"

class Spring2D 
{
public:
	float vx, vy; // The x- and y-axis velocities
	float x, y; // The x- and y-coordinates
	float gravity;
	float mass;
	float radius;
	float stiffness;
	float damping;

	Spring2D();
	~Spring2D();
	Spring2D(float xpos, float ypos, float m, float g);
	void update(float targetX, float targetY);
	void display(float nx, float ny);

};

#endif //#ifndef _SPRING_H_  

Spring.cpp:

#include "Spring.h"

Spring2D::Spring2D():
radius(20),
stiffness(0.2),
damping(0.7)
{
}

Spring2D::~Spring2D()
{
}

Spring2D::Spring2D(float xpos, float ypos, float m, float g):
radius(20),
stiffness(0.2),
damping(0.7) 
{
	x = xpos;
	y = ypos;
	mass = m;
	gravity = g;
}

void Spring2D::update(float targetX, float targetY) 
{
	float forceX = (targetX - x) * stiffness;
	float ax = forceX / mass;
	vx = damping * (vx + ax);
	x += vx;
	float forceY = (targetY - y) * stiffness;
	forceY += gravity;
	float ay = forceY / mass;
	vy = damping * (vy + ay);
	y += vy;
}

void Spring2D::display(float nx, float ny) 
{
	//noStroke();
	//ellipse(x, y, radius*2, radius*2);
	//stroke(255);
	//line(x, y, nx, ny);
	ofSetColor(0x000000);
	ofEllipse(x, y, radius*2, radius*2);
	ofSetColor(0xFFFFFF);
	ofLine(x, y, nx, ny);
}

Тут всё просто. Делаем все данные и методы публичными, добавляем конструктор и деструктор.
Присваивание значений переменным выносим в инициализацию конструктора.
Более важные изменения вносятся в метод display(). Функции рисования Processing необходимо заменить на соответствующие функции OpenFrameworks-а.

Переходим к функции начальной установки setup():

float gravity = 6.0;
float mass = 2.0;

void setup() 
{
  size(200, 200);
  smooth();
  fill(0);
  // Inputs: x, y, mass, gravity
  s1 = new Spring2D(0.0, width/2, mass, gravity);
  s2 = new Spring2D(0.0, width/2, mass, gravity);
}

и просто переносим данный код в аналогичный метод:

void testApp::setup(){

	width = 200;
	height = 200;

	//--------------------------
	gravity = 6.0;
	mass = 2.0;

	//size(200, 200);
	ofSetWindowShape(200, 200); // размер окна
	//smooth();
	ofEnableSmoothing();
	//fill(0);
	ofBackground(0, 0, 0); // чёрный фон
	
	// Inputs: x, y, mass, gravity
	s1 = new Spring2D(0.0, width/2, mass, gravity);
	s2 = new Spring2D(0.0, width/2, mass, gravity);

	//------------------------

	//lets make our circles look a little nicer!
	ofSetCircleResolution(50);
	
	ofSetVerticalSync(true);
	ofSetFrameRate(50);

	mouseX=0;
	mouseY=0;
	mouseClickX=0;
	mouseClickY=0;
}

В класс testApp необходимо добавить переменные width и height для хранения размеров окна. А так же переменные mouseX и mouseY, которые понадобятся в методе draw() и которые содержат текущие координаты указателя мышки:

void testApp::mouseMoved(int x, int y ){
	printf("[i][mouseMoved] x: %d y: %d\n", x, y);
	mouseX=x;
	mouseY=y;
}

Осталось переписать функцию

void draw() 
{
  background(204);
  s1.update(mouseX, mouseY);
  s1.display(mouseX, mouseY);
  s2.update(s1.x, s1.y);
  s2.display(s1.x, s1.y);
}

в одноимённом методе

void testApp::draw(){

	//background(204);
	ofBackground(204, 204, 204); // серый фон

	//s1.update(mouseX, mouseY);
	//s1.display(mouseX, mouseY);
	//s2.update(s1.x, s1.y);
	//s2.display(s1.x, s1.y);
	if(s1){
		s1->update(mouseX, mouseY);
		s1->display(mouseX, mouseY);
	}
	if(s2){
		s2->update(s1->x, s1->y);
		s2->display(s1->x, s1->y);
	}
}

Вот и всё! Вот что получилось:

Скачать программу + исходники. (1.9 Mb)
Для запуска программы, в каталоге bin должны находиться все требуемые dll-библиотеки.

Вывод:
openFrameworks ещё доволно молод и по сравнению с Processing-ом многих простых функций ему ещё очень не хватает. Но его простота и прозрачность — это замечательный плюс, который позволяет программировать на С++ захватывающие графические и интерактивные приложения.

Ссылки
http://thomas-gerhardt.com/itp/2008/04/03/open-frameworks-vs-processing/

По теме
Processing и Arduino
openFrameworks и Arduino


0 комментариев на «“openFrameworks vs Processing”»

    • усехов 🙂 можно начать с перевода скетчей Processing-а 😉

Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Arduino Bluetooth CraftDuino DIY Google IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд юмор

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение