how i display the coordinates of a random triangle in a graph which ranges from -10 to +10 in XY axis with the points like A(2,1) etc with arcs in each corner, in actionscript 2.0
问题:
回答1:
OK, so far we've done triangles with arcs, triangles on a grid, and triangles with coordinates. Now it's time to combine all these into one piece of code. You've asked for a grid size of -10 to +10, but it's only a little bit more work to make it work for any size grid (well, within limits).
We need to deal with converting between your chosen range (-10 to +10) and the size of your stage (in pixels). The trick to this is to create a movieClip ('myGraph') to hold our -10 to +10 grid, and then scale it up to fit the size of the stage (we'll leave a 20 pixel margin around the edge); we'll calculate a rectangle ('displayRect') to represent the maximum size we'd like myGraph to be. We also want to position myGraph so it's origin is in the right place, and flip it vertically so the Y-axis increases as you move upward on the screen.
Once we've done all that, we can draw inside myGraph using our desired units (-10 to +10) with no further need to convert into pixels - the scaling of myGraph takes care of that for us automatically.
Next, we make a 'grid' clip inside myGraph, and draw a grid in it using the drawGrid() function.
Then we make an 'arcTriangle' clip inside myGraph, and draw our triangle inside it. We use the same technique as previously, by drawing our triangle, drawing a red circle at each corner, then using a copy of the triangle as a mask to reveal only the internal arcs of the circles. Then we make a textField at each corner to display the coordinates of each point (note that these need to be scaled back up to normal size, otherwise the text is too small to read!).
Lastly, we add an onRelease function to myGraph, which draws a new random arcTriangle when clicked.
alt text http://roi.webfactional.com/img/so/arctriangles.jpg
Here's the code...
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 (tick http://roi.webfactional.com/img/so/so_tick.png) on the left-hand side. Thank you.