好的,到目前为止我们已经完成了带圆弧的三角形, 网格上的三角形, and 带坐标的三角形。现在是时候将所有这些组合成一段代码了。您要求网格大小为 -10 到 +10,但只需多做一点工作即可使其适用于任何大小的网格(好吧,在限制范围内)。
我们需要处理您选择的范围(-10 到 +10)和舞台大小(以像素为单位)之间的转换。这样做的技巧是创建一个 movieClip ('myGraph') 来保存 -10 到 +10 的网格,然后将其放大以适应舞台的大小(我们将在边缘周围留下 20 像素的边距);我们将计算一个矩形('displayRect')来表示我们希望 myGraph 的最大尺寸。我们还希望定位 myGraph,使其原点位于正确的位置,并垂直翻转它,以便 Y 轴随着您在屏幕上向上移动而增加。
完成所有这些后,我们可以使用所需的单位(-10 到 +10)在 myGraph 中进行绘制,而无需进一步转换为像素 - myGraph 的缩放会自动为我们处理这一问题。
接下来,我们在 myGraph 中创建一个“网格”剪辑,并使用 drawGrid() 函数在其中绘制网格。
然后我们在 myGraph 中创建一个“arcTriangle”剪辑,并在其中绘制三角形。我们使用与之前相同的技术,绘制三角形,在每个角绘制一个红色圆圈,然后使用三角形的副本作为蒙版以仅显示圆圈的内部弧。然后我们在每个角创建一个文本字段来显示每个点的坐标(请注意,这些需要缩放回正常大小,否则文本太小而无法阅读!)。
最后,我们向 myGraph 添加一个 onRelease 函数,该函数在单击时绘制一个新的随机 arcTriangle。
![alt text](https://i.stack.imgur.com/TATeR.jpg)
(source: webfactional.com)
这是代码...
import flash.geom.Point;
import flash.geom.Rectangle;
var margin:Number = 20;//leave a margin around the graph...
//...calculate the largest extent (displayRect) that we want our graph to be displayed in:
var displayRect = new Rectangle(margin, margin, Stage.width-margin-60, Stage.height-2*margin);
//make the 'graph' clip:
var myGraph:MovieClip = this.createEmptyMovieClip("myGraph", this.getNextHighestDepth());
myGraph.extents = new Rectangle(-10, -10, 20, 20);//you can change this to set a different size of grid
//calculate the length of one local unit in pixels...
myGraph.unit = Math.min((displayRect.height)/myGraph.extents.height, (displayRect.width)/myGraph.extents.width);
//... and scale the graph clip so it fits inside the displayRect
myGraph._xscale = myGraph.unit*100;
myGraph._yscale = -myGraph.unit*100;// this one is negative, so Y increases upwards
//calculate the origin of myGraph...
myGraph.origin = new Point(displayRect.left-myGraph.unit*myGraph.extents.left, displayRect.top+myGraph.unit*myGraph.extents.bottom);
//... and move myGraph into the correct position
myGraph._x = myGraph.origin.x;
myGraph._y = myGraph.origin.y;
//draw a blank grid
drawGrid(myGraph.createEmptyMovieClip("grid", 0), myGraph.extents);
//draw a random triangle with arcs
arcTriangle(myGraph.createEmptyMovieClip("arcTriangle", 1), myGraph.extents);
//add a function to draw a new triangle when the graph is clicked:
myGraph.onRelease = function() {
arcTriangle(myGraph.createEmptyMovieClip("arcTriangle", 1), myGraph.extents);
}
//-------------------------------------
// All the functions are defined below:
function drawGrid(mc:MovieClip, rect:Rectangle):Void {
//this is a function to draw the grid and axes
//draw a light-grey background
mc.beginFill(0xF8F8F8);
mc.moveTo(rect.left, rect.bottom);
mc.lineTo(rect.left, rect.top);
mc.lineTo(rect.right, rect.top);
mc.lineTo(rect.right, rect.bottom);
mc.lineTo(rect.left, rect.bottom);
mc.endFill();
//draw a light-blue grid
var unit:Number = 1;
mc.lineStyle(1, 0x0000FF, 20, true, "none", "round", "round");
var i:Number = rect.x;
do {
i = i+unit;
mc.moveTo(i, rect.bottom);
mc.lineTo(i, rect.top);
} while (i<rect.right);
i = rect.bottom;
do {
i = i-unit;
mc.moveTo(rect.left, i);
mc.lineTo(rect.right, i);
} while (i>rect.top);
//draw the X-axis and Y-axis in dark grey
mc.lineStyle(2, 0x808080, 100, true, "none", "round", "round");
mc.moveTo(rect.left, 0);
mc.lineTo(rect.right, 0);
mc.moveTo(0, rect.bottom);
mc.lineTo(0, rect.top);
}
function randomPoint(rect:Rectangle):Point {
//this is a function which returns a random point within a given rectangle
var p:Point = new Point(rect.x+Math.floor(Math.random()*rect.width), rect.y+Math.floor(Math.random()*rect.height));
return p;
}
function drawTriangle(mc:MovieClip, q1:Point, q2:Point, q3:Point):Void {
//this function draws a triangle through 3 points
var stroke = 2; //(line weight of triangle)
mc.lineStyle(stroke, 0x000000, 100, true, "none", "round", "round");
mc.moveTo(q1.x, q1.y);
mc.lineTo(q2.x, q2.y);
mc.lineTo(q3.x, q3.y);
mc.lineTo(q1.x, q1.y);
}
function drawCircle(mc:MovieClip, x:Number, y:Number):Void {
//this draws a red circle, centred on (x,y)
//we want the circle to always appear the same size,
//independently of our scaling of myGraph,
//so we need to set the radius accordingly:
var radius:Number = 18/mc._parent._parent.unit;
//AS2 has no direct way of drawing a circle,
//so we need to construct one out of 8 bezier curves:
var k1:Number = Math.tan(Math.PI/8)*radius;
var k2:Number = Math.sin(Math.PI/4)*radius;
with (mc) {
lineStyle(2, 0xFF0000, 100, true, "none", "round", "round");
moveTo(x+radius, y);
curveTo(radius+x, k1+y, k2+x, k2+y);
curveTo(k1+x, radius+y, x, radius+y);
curveTo(-k1+x, radius+y, -k2+x, k2+y);
curveTo(-radius+x, k1+y, -radius+x, y);
curveTo(-radius+x, -k1+y, -k2+x, -k2+y);
curveTo(-k1+x, -radius+y, x, -radius+y);
curveTo(k1+x, -radius+y, k2+x, -k2+y);
curveTo(radius+x, -k1+y, radius+x, y);
}
}
function arcTriangle(t:MovieClip, rect:Rectangle):MovieClip {
//main function to draw a triangle with corner arcs
//define 3 random points (stored as properties of t)
t.p=new Array(3);
t.p[0] = randomPoint(rect);
t.p[1] = randomPoint(rect);
t.p[2] = randomPoint(rect);
//draw a triangle
t.createEmptyMovieClip("triangle", 0);
drawTriangle(t.triangle, t.p[0], t.p[1], t.p[2]);
//draw a filled triangle to use as a mask
t.createEmptyMovieClip("mask", 1);
t.mask.beginFill(0xF0F0F0);
drawTriangle(t.mask, t.p[0], t.p[1], t.p[2]);
t.mask.endFill();
t.mask._alpha = 0;
//add a red circle to each corner
t.createEmptyMovieClip("arcHolder", 2);
drawCircle(t.arcHolder, t.p[0].x, t.p[0].y);
drawCircle(t.arcHolder, t.p[1].x, t.p[1].y);
drawCircle(t.arcHolder, t.p[2].x, t.p[2].y);
//mask the circles so only the interior arcs are visible
t.arcHolder.setMask(t.mask);
//show the coordinates for each point
var tf:TextField;
for (var i = 0; i<3; i++) {
tf = t.createTextField("text"+i, i+3, t.p[i].x, t.p[i].y, 1, 1);
tf.autoSize = true;
tf._xscale = 10000/t._parent._xscale;
tf._yscale = 10000/t._parent._yscale;
//use unicode values to get "A", "B" and "C":
tf.text = String.fromCharCode(65+i)+"("+t.p[i].x+", "+t.p[i].y+")";
}
return t;
}
Remember: you can accept a favourite answer to each of your questions by clicking the big tick-mark (
) on the left-hand side. Thank you.