一、前言
因为导航软件现在几乎人人都会用了,相信大家现在都已经不会迷路,但是还是难以避免会有问路的,会不会觉得难以描述或者并不形象呢?现在的每一栋大厦或者场所必定都会有安全疏散图相信大家都知道,但是会有多少人每次花心思先去看一看呢?想必现在开车的人最头疼的一件事就是找停车场吧,即使找到了停车场,找不到入口?还得绕一圈发现进到了最堵得地方有没有觉得好难受。我们能不能像下面的藏宝图一样设计出来路线图呢?
二、绘图软件简介
根据我们这次作业的要求:编写一个“绘画系统”,提供一系列的绘画材料给用户操作,以创作动态交互作品,也就是创作一个app,看起来比较像“画画工具”,再加上之前的问题,我的主题便定了下来,一个可以导航的绘图软件。
其主界面如下:
看起来十分的简洁,接下来我来介绍他所具有的功能:左边的白色区域是绘画的区域,右面是工具栏,工具栏的最下面首先是brush:笔刷的类型,具体的每种笔刷会在之后介绍,按键C可以清屏,↕按键可以换笔刷的类型,L/S按键用来保存和读取你的画(还未完善),在上面是一个表设置他的原因我会在之后解释,再上面是颜色盘,对应的是画笔和背景的颜色。
三、功能设计
1.钟表的设计:其实加入这个钟表的原因有很多,起因是我自己在设计绘画板的时候忘记了吃饭,就发现注意时间的重要性,就有了加入表的想法,主要是我考虑到用我的这个系统画这些设计图的时候可能都会很赶时间比如说想画一个找路的图,疏散图,找地点的图,有一个表在时刻的提醒着是非常不错的。
钟表源代码:
var cx=paintingWidth+80, cy=470;
var secondsRadius;
var minutesRadius;
var hoursRadius;
var clockDiameter;
function setup() {
var clockradius = 50;
secondsRadius = clockradius * 0.71;
minutesRadius = clockradius * 0.60;
hoursRadius = clockradius * 0.50;
clockDiameter = clockradius * 1.7;
function draw() {
//表
push();
noStroke();
fill(244,122,158);
ellipse(cx, cy, clockDiameter + 25, clockDiameter + 25);
fill(237,34,93);
ellipse(cx, cy, clockDiameter, clockDiameter);
// 时间
var s = map(second(), 0, 60, 0, TWO_PI) - HALF_PI;
var m = map(minute() + norm(second(), 0, 60), 0, 60, 0, TWO_PI) - HALF_PI;
var h = map(hour() + norm(minute(), 0, 60), 0, 24, 0, TWO_PI * 2) - HALF_PI;
// 表针
stroke(255);
strokeWeight(1);
line(cx, cy, cx + cos(s) * secondsRadius, cy + sin(s) * secondsRadius);
strokeWeight(2);
line(cx, cy, cx + cos(m) * minutesRadius, cy + sin(m) * minutesRadius);
strokeWeight(4);
line(cx, cy, cx + cos(h) * hoursRadius, cy + sin(h) * hoursRadius);
// 每分钟的点
strokeWeight(2);
beginShape(POINTS);
for (var a = 0; a < 360; a+=6)
{
var angle = radians(a);
var x = cx + cos(angle) * secondsRadius;
var y = cy + sin(angle) * secondsRadius;
vertex(x, y);
}
endShape();
pop();
}
2.颜色块的设计:我按照了我们经常用到的画图软件的调色板设计了这个,只是加入了三原色(红绿蓝)和二次色(青黄品红)和黑白。
颜色块的代码:
var R=0;G=0;B=0;
var r=255;g=255;b=255;
//画笔颜色
buttonW=Button(paintingWidth+20,20,255,255,255,30);
buttonR=Button(paintingWidth+20,70,255,0,0,30);
buttonG=Button(paintingWidth+20,120,0,255,0,30);
buttonB=Button(paintingWidth+20,170,0,0,255,30);
buttonQ=Button(paintingWidth+20,220,0,255,255,30);
buttonF=Button(paintingWidth+20,270,255,0,255,30);
buttonH=Button(paintingWidth+20,320,255,255,0,30);
buttonBL=Button(paintingWidth+20,370,0,0,0,30);
function Button(x,y,R,G,B,size)
{
this.bx=x;
this.by=y;
var boxSize = 30;
stroke(R,G,B);
fill(R,G,B);
rect(bx, by, boxSize, boxSize);
}
//背景颜色
buttonW2=Button(paintingWidth+110,20,255,255,255,30);
buttonR2=Button(paintingWidth+110,70,255,0,0,30);
buttonG2=Button(paintingWidth+110,120,0,255,0,30);
buttonB2=Button(paintingWidth+110,170,0,0,255,30);
buttonQ2=Button(paintingWidth+110,220,0,255,255,30);
buttonF2=Button(paintingWidth+110,270,255,0,255,30);
buttonH2=Button(paintingWidth+110,320,255,255,0,30);
buttonBL2=Button(paintingWidth+110,370,0,0,0,30);
function mousePressed()
{
//print("mousePressed:" + millis());
if(mouseInPaintingRect()==1)
{
brushStroke();
}
//画笔颜色
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=20 && mouseY<=50)
{
R=255;
G=255;
B=255;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=70 && mouseY<=100)
{
R=255;
G=0;
B=0;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=120 && mouseY<=150)
{
R=0;
G=255;
B=0;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=170 && mouseY<=200)
{
R=0;
G=0;
B=255;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=220 && mouseY<=250)
{
R=255;
G=0;
B=255;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=270 && mouseY<=300)
{
R=255;
G=0;
B=255;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=320 && mouseY<=350)
{
R=255;
G=255;
B=0;
}
if(mouseX>=paintingWidth+20 && mouseX<=paintingWidth+50 &&
mouseY>=370 && mouseY<=400)
{
R=0;
G=0;
B=0;
}
//背景颜色
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=20 && mouseY<=50)
{
r=255;
g=255;
b=255;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=70 && mouseY<=100)
{
r=255;
g=0;
b=0;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=120 && mouseY<=150)
{
r=0;
g=255;
b=0;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=170 && mouseY<=200)
{
r=0;
g=0;
b=255;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=220 && mouseY<=250)
{
r=255;
g=0;
b=255;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=270 && mouseY<=300)
{
r=255;
g=0;
b=255;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=320 && mouseY<=350)
{
r=255;
g=255;
b=0;
}
if(mouseX>=paintingWidth+110 && mouseX<=paintingWidth+140 &&
mouseY>=370 && mouseY<=400)
{
r=0;
g=0;
b=0;
}
}
2.笔刷的类型:
(1)默认笔刷:画出来的效果和普通笔刷是一样的,旁边有各种的颜色可以选择,画出来的效果如下:
(2)严重路塞路线画笔:用了红色的颜色来体现路塞的状态,并且是静态的给人一种已经堵死了的感觉。,具体效果如下:
(3)轻微路塞路线画笔:相比严重的路塞,我们继续使用红色表明此处路塞的状态,但是让他有较慢的流动效果表明还能移动。效果与畅通一同展示
(4)畅通道路路线画笔:我们用绿色的线段和较快的移动速度表明这里的移动较快,以体现畅通的效果。
(5)水管道路路线画笔:我们将每个小小的圆变成了圆环,并且改为蓝色,如果有人想用这个软件画水果图或者河流均可以用这个标识以上三种效果如下:
(5)五角星的标识:可以利用不同的颜色来表示不同的意义,用来作为终点或者标志在地图上显示,效果如下:
(6)错误标识:这个标识我最初的想法是用来标识此处禁止通行之类的位置,但是我发现也可以做一个地点标识,像不像一个藏宝地图的重点。
(7)源点标识:我们需要一个很好的标识来表明自己的位置或者其他标志,所以一个源点的标志最好的能够表现这个了,效果如下:
笔刷类型的源码:
var brushes = [
brush_0, // 0
brush_1, // 1
brush_2, // 2
brush_3, // 3
brush_4, // 4
brush_5, // 5
brush_6, // 6
brush_7, // 7
];
fnction brush_0()
{
var phase = millis()/30;
append(circles, new route1(mouseX,mouseY,0,0,phase,R,G,B));
}
function brush_1()
{
var phase = millis()/30;
append(circles, new route2(mouseX,mouseY,6,0,phase,255,0,0));
}
function brush_2()
{
var phase = millis()/30;
append(circles, new route2(mouseX,mouseY,6,2,phase,255,0,0));
}
function brush_3()
{
var phase = millis()/30;
append(circles, new route3(mouseX,mouseY,6,10,phase,0,255,0));
}
function brush_4()
{
var phase = millis()/30;
append(circles, new route4(mouseX,mouseY,0,6,2,phase,0,0,255));
}
function brush_5()
{
var phase = millis()/30;
append(circles, new star(mouseX, mouseY, 10, 25, 5,R,G,B));
}
function brush_6()
{
var phase = millis()/30;
append(circles, new cha(mouseX, mouseY, 50,R,G,B));
}
function brush_7()
{
var phase = 1*millis()/1000;
append(circles, new sourse(mouseX,mouseY,0,15,5,phase,R,G,B));
}
function route1(
x,y, amp, freq, phase,R,G,B )
{
this.x = x;
this.y = y;
this.R = R;
this.G = G;
this.B = B;
this.draw = function()
{
push();
noStroke();
strokeWeight(5);
stroke(R,G,B,50);
fill(0,0);
translate(this.x,this.y);
ellipse(0,0,5,5);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function route2(
x,y, amp, freq, phase,R,G,B )
{
this.x = x;
this.y = y;
this.R = R;
this.G = G;
this.B = B;
this.amplitude = amp;
this.frequence= freq;
this.phase = phase;
this.draw = function()
{
var secs = millis()/1000.0;
var Bias =
this.amplitude *
sin(this.frequence * secs + this.phase);
push();
noStroke();
strokeWeight(5);
stroke(R,G+Bias*255,B+Bias*255,50);
fill(0,0);
translate(this.x,this.y);
ellipse(0,0,5,5);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function route3(
x,y, amp, freq, phase,R,G,B )
{
this.x = x;
this.y = y;
this.R = R;
this.G = G;
this.B = B;
this.amplitude = amp;
this.frequence= freq;
this.phase = phase;
this.draw = function()
{
var secs = millis()/1000.0;
var Bias =
this.amplitude *
sin(this.frequence * secs + this.phase);
push();
noStroke();
strokeWeight(5);
stroke(R+Bias*255,G,B+Bias*255,50);
fill(0,0);
translate(this.x,this.y);
ellipse(0,0,5,5);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function route4(
x,y, radius,amp, freq, phase,R,G,B )
{
this.x = x;
this.y = y;
this.R = R;
this.G = G;
this.B = B;
this.radius = radius;
this.amplitude = amp;
this.frequence= freq;
this.phase = phase;
this.draw = function()
{
var secs = millis()/1000.0;
var rBias =
this.amplitude *
sin(this.frequence * secs + this.phase);
push();
noStroke();
strokeWeight(50);
stroke(R+rBias*255,G+rBias*255,B,50);
fill(0,0);
translate(this.x,this.y);
ellipse(0,0,5,5);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function star(x, y, radius1, radius2, npoints,R,G,B) {
this.x=x;
this.y=y;
var angle = TWO_PI / npoints;
var halfAngle = angle/2.0;
this.draw = function()
{
push();
stroke(R,G,B);
beginShape();
for (var a = 0; a < TWO_PI; a += angle) {
var sx = x + cos(a) * radius2;
var sy = y + sin(a) * radius2;
vertex(sx, sy);
sx = x + cos(a+halfAngle) * radius1;
sy = y + sin(a+halfAngle) * radius1;
vertex(sx, sy);
}
endShape(CLOSE);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function cha(x, y, size, R,G,B) {
this.x=x;
this.y=y;
m=size/4;
n=size/2;
this.draw = function()
{
push();
fill(R,G,B);
noStroke();
quad(x-n, y+n, x-m, y+n, x+n, y-n, x+m, y-n);
quad(x+m, y+n, x+n, y+n, x-m, y-n, x-n, y-n);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
}
function sourse(x,y,radius, amp, freq, phase,R,G,B )
{
this.x = x;
this.y = y;
this.radius = radius;
this.amplitude = amp;
this.frequence= freq;
this.phase = phase;
this.draw = function()
{
var secs = millis()/1000.0;
var rBias =
this.amplitude *
sin(this.frequence * secs + this.phase);
var r = this.radius + rBias;
push();
noStroke();
strokeWeight(0.2);
stroke(R,G,B,50);
fill(R,G,B,10);
translate(this.x,this.y);
scale(r,r);
ellipse(0,0,1,1);
pop();
}
this.toJson = function()
{
var jsonObj = {};
jsonObj.x = this.x;
jsonObj.y = this.y;
jsonObj.radius = this.radius;
jsonObj.amplitude = this.amplitude;
jsonObj.frequence = this.frequence;
jsonObj.phase = this.phase;
return jsonObj;
}
this.fromJson = function(jsonObj)
{
this.x = jsonObj.x;
this.y = jsonObj.y;
this.radius = jsonObj.radius;
this.amplitude = jsonObj.amplitude;
this.frequence = jsonObj.frequence;
this.phase = jsonObj.phase;
}
2.功能应用
可能到现在,也有人想不到在那里地方能用到,我就将我的一些想法展示出来。
(1)从宿舍到数媒楼的路线图:每次上课的高峰期,人群都能“堵车”,我们来看一下当时的状况大概是如何的(我用紫色的源点来表示我们的宿舍,五角星表明数媒楼,在刚出宿舍的这段路上是最为拥挤的,之后上了大道会比较的通畅,当然我们发现从南门走会更加的通畅,但是走的远啊)。
(2)一个楼层的疏散路线图:楼层的设计是我自己假想的,加上这些流动的效果和颜色的差别是不是让这个图表现的更加明显了。(我们继续用紫色源点标识自己的原来位置,绿色五角星表示我们要去的安全通道,还有错误标志表明地方不能走)
四、扩展绘画概念的理念
绘画在技术层面上,是一个以表面作为支撑面,再在其之上加上颜色的做法,那些表面可以是纸张或布,加颜色的工具可以通过画笔、也可以通过刷子、海绵或是布条等。在艺术用语的层面上,绘画的意义亦包含利用此艺术行为再加上图形、构图及其他美学方法去达到画家希望表达的概念及意思。来比较一下我的这个绘画板和常规的画板之间的异同吧。
1.工具方面
在默认的画笔和一些普通的图形上,常规的绘画系统也是有的,在常规的绘画系统上,画线工具也是有的,但是形式都过于单一了,只能画出纯色的线段,这也是我为什么没有选择设计直接的画线工具,而是由密集的点组成线,这样每一个点都是一个单独的结构,我们可以更好地改变这一条线。例如在我的系统中,我想能用间隔的线段画出流向的感觉,再加上点不断地变化,一个线段工具就变得更加灵活多样,其中的参数可以有更多的改变。
2.理念方面
我的绘画系统画出的作品很有方向性,相对于常规绘画系统,很多的功能我可能都没有;但是因为我想表达出流动的效果所以在疏散图啊,导航图啊一些方面是更加的好的,因为常规画板的理念是想让人们更大范围的创作,没有任何的方向引导,但是我的理念更倾向于表现一些流动的事物,用流动的先画出有方向性的图。
3.视觉的方面
因为制作出来的图是动态的,所以立马就变得比静态图更加的有视觉上的冲击,而且,更加能让我们的引导效果加强,因为流动的效果就更加的有引导效果,制作出来的图上让人看起来就很有方向性,主要两个线段的颜色采用的红,绿也很对应他们的拥堵和畅通效果。
4.呈现效果
我认为在呈现的效果方面是有所加成的,我们都看到过静止的一些导航软件的导航图片,或者疏散图,因为是静态的所以基本的区别点在什么?形状;颜色无疑是两个最大的点,而在系统中加上了动态效果后又有了一个很大的区别点,绿色代表畅通,流速快也代表畅通当合在一起之后的线段就表现效果就更加的显著了,这样与流速慢的红色线段强烈的对比。
5.应用
对于这个小画板的应用我认为是非常的广,比如说我们已经提到的路线图,疏散图。比如我们的晚会,会议等场合的引导图;朋友之间询问具体地点,可以将其绘画出来告知;某一个地段的拥堵状况我们也可以来描述;或者是画一些工业的草图,比如说水管的线路图,铁路的路线图等等。其动态的效果要比常规绘画效果更佳强。
五、总结
我的想法就来自生活中,在一个给人描述路线的情景之下,因为我认为在介绍的过程中,很难表达的清楚地点的具体位置,你该从哪里走,所以想到了这个主题。在这个绘画系统中我最大的想突出的点是流动性,流动性在画中第一有十分充足的引导作用,大家看到流动的图基本都会顺着这个流动的方向跟随下去;第二表现力强,相对于静态的图片,动态的流动效果更加的凸显出其表达的内容。因为在常规的绘画中很难表达出这种效果,所以在这个绘画系统中画出来图感觉方向性很强。