Flex 3, ActionScript 3, Flash player 9.
I have a picture in a BitmapData object. And an array of points. I nead to erase the part of the picture inside a polygon specified by the points. In other words, draw a polygon specified by the points and fill it with transparency.
Any ideas on how it can be done?
Got it working with the following code:
var shape:Shape = new Shape();
shape.graphics.beginFill(0x000000, 1); // solid black
shape.graphics.moveTo(points[0].x, points[0].y);
points.forEach(function (p:Point, i:int, a:Array):void {
shape.graphics.lineTo(p.x, p.y);
});
shape.graphics.endFill();
data.draw(shape, null, null, "erase");
For a rectangle, you can use fillRect. For a polygon you are gonna have to draw the polygon in a totally different color (than other colors in the bitmap) and use floodFill - but I don't know how to draw a polygon. There is no method in bitmap data class to draw lines. Another option would be to write your own logic to find pixels inside the polygon and use setPixel32 method to set their alphas to zero.
This wikipedia page describes algorithms to find if a point is inside a given polygon. You might find it useful.
Related
I am trying to implement a 2D selection window that can select the 3D vertices inside the 2D window (indicated by dashed cyan rectangle). Each of my 3D models is currently a composite group of MeshView's, one MeshView per face. My plan was to iterate over each face (MeshView) and check if the 2D bounds intersect with the selection box bounds (I am planning to update this later using an Atlas texture to reduce the amount of meshes, but for now I just want the selection mechanism working).
Currently I have the following, but this isn't correct.
val selectionBounds = selectionRectangle.boundsInParent
val localBounds = meshView.localToScene(meshView.boundsInLocal, true)
if (selectionBounds.intersects(localBounds))
// do something with the mesh in meshView
My subscene contains a perspective camera, now I saw two useful posts:
Convert coordinates from 3D scene to 2D overlay
How to get 2D coordinates on window for 3D object in javafx
I think I have to first project the meshView's bounds properly using my perspective camera. But I am unsure how to proceed, do I have to project every 3D point in the local bounds to 2D as is done in referenced question 2 (above). Not very familiar with the math, or related concepts, any help would be appreciated.
(wink, wink MVP José)
EDIT 1:
After José's suggestion I added red bounding boxes for each meshview which gives the following result:
Apparently it adds some offset which appears to be the same regardless of the camera rotation. Here the red boxes are drawn around each meshview. Will investigate further..
EDIT 2:
I use a Pane which contains the SubScene and another Node. This is done to control the sizing of the SubScene and to reposition/resize the other Node accordingly by overriding the layoutChildren method, as such (this is in Kotlin):
override fun layoutChildren() {
val subScene = subSceneProperty.get()
if (subScene != null){
subScene.width = width
subScene.height = height
}
overlayRectangleGroup.resize(width, height)
val nodeWidth = snapSize(overlayMiscGroup.prefWidth(-1.0))
val nodeHeight = snapSize(overlayMiscGroup.prefHeight(-1.0))
overlayMiscGroup.resizeRelocate(width - nodeWidth, 0.0, nodeWidth, nodeHeight)
}
I am trying to highlight an Area that gets intersected by 2 Circle:
Example 1.:
The Yellow dots get, for testing purposes, random values. Those are used to draw a circle around, as well as to store an ellipse in the Background. In the Case of no intersection, the GUI acts correctly and display this:
After the random Values, the Shapes intersect. As I cannot seem to be able to add the new Shape made trough .intersect(), I just did a quick sp.setContent(), and got this image:
This basicly shows me the intersected space and colors it blue.
Everything is drawn on a Canvas, which basicly does the following:
Canvas canvas = new Canvas(250, 250);
....
gc = canvas.getGraphicsContext2D();
canvas.setHeight(imgTemp.getHeight());
canvas.setWidth(imgTemp.getWidth());
gc.drawImage(imgTemp, 0, 0);
Aswell as with some other Loops to draw the shapes and the circles.
Now, the code for the intersect is the following:
if (!(e.equals(eT))) {
if (e.getBoundsInParent().intersects(eT.getBoundsInParent())) {
System.out.println("Collision detected!");
Shape inter = Shape.intersect(e, eT);
if(inter.getBoundsInLocal().getWidth() > 0 && 0 < inter.getBoundsInLocal().getHeight()){
inter.setFill(BLUE);
inter.setStrokeWidth(3);
sp.setContent(inter);
}
}
I'm not that used to JavaFX and have only begun really working on it this Weekend for a small Project, but I am guessing that I might need to change from canvas to something else to make use of the shapes? Or is there a way to "tranform" the Shape of the intersect into something drawable by GraphicsContext2D?
Why don't you just put your Canvas into a Group and then add your shapes to the same Group. Why would you insist on drawing everything into the Canvas? A Canvas is just a Node like all the other Shapes and you can mix them freely in the SceneGraph.
Another question would be why you are using the Canvas at all if you have already realized that this leads to problems in your case.
I want to extend Shape class in paper.js to draw polygon like pentagon or hexagon
I don't want to use Path.RegularPolygon as it is creating a problem while rotating object along with the path.
Can anyone please provide me sample code on how to extend Shape class to create Polygon in paperjs
Just use
var hexagon = new Path.RegularPolygon(new Point(xPos, yPos), 6, radius);
hexagon.rotate( 15 );
paper.view.draw();
I need to check if some shapes are colliding in a 2D world.
To check collision between circle and rectangle I found this:
Collision Detection with Rotated Rectangles
But now I need to add another shape to this code (triangle), and the triangle can rotate too.
How can I do that?
This JSTS example (in javascript) shows how to intersect two polygons.
https://github.com/bjornharrtell/jsts/blob/master/examples/overlay.html
In order to modify the example to make one of them into a circle, use this snippet:
// this returns a JSTS polygon circle approximation with provided center and radius
function pointJSTS(center,radius){
var point = new jsts.geom.Point(center);
return point.buffer(radius);
}
// ....
// insert this into the example above at line 17
b = pointJSTS({x:10,y:20}, 40);
Further modification to the example to make the first polygon into a triangle is trivial.
This question already has an answer here:
Can I get vector data back out out of a Graphics object?
(1 answer)
Closed 9 years ago.
EDIT (for clarification):
I have a vector image with a simple contour, an irregular closed polygon.
I need to import it into Flash in a way that I can then programmatically access each of the segments that form the polygon.
Importing the vector image into the library as a MovieClip wasn't good because all I get is a shape from which I can take no geometry information at all.
My goal is being able to calculate the polygon's area and also calculating the intersection between the polygon and another polygon.
I guess I could write an Illustrator script that reads all the segments and writes a CSV files with their coordinates, but there has to be a simpler way, I mean, they're both vectorial, they should understand each other.
Thanks!
.
-- Old Post: --
I have a contour in vector graphics that I imported to the Flash library as a movieclip.
I Instanciate the movieclip and it has a Shape child which is the actual contour.
I need to be able to access the contour segments, i.e. the polygon's sides, to be able to get their starting and ending points, is there a way?
the Graphics class only allows to draw but what you draw, as with the Shape class, are not objects, it's not a polygon with sides or whatever.
Am I being clear?
Thanks
There is no way to read the data of a Graphics object (which is essentially what contains the information that you are after.) This applies to any vector graphics object that has already been drawn, either by the Graphics/drawing API itself, or in Flash CS3/CS4, or was embedded using the [Embed] meta-tag.
Your best bet if you need to calculate the algebraic area, or for some other reason retain the vectors in your algorithms, is definitely exporting an SVG or some single-purpose format (like a CSV of the points) from Illustrator, and parsing that in ActionScript.
Another option is to use a BitmapData, and draw the Shape object onto that, then counting the colored (opaque) pixels to numerically calculate it's area.
var bmp : BitmapData = new BitmapData(myShape.width, myShape.height, true, 0);
bmp.draw(myShape);
var i : uint;
var area : uint = 0;
var num_pixels : uint = bmp.width*bmp.height;
for (i=0; i<num_pixels; i++) {
var px : uint = bmp.getPixel32(i%bmp.width, Math.floor(i/bmp.height));
// Determine from px color/alpha whether it's part of the shape or not.
// This particular if statement should determine whether the alpha
// component (first 8 bits of the px integer) are greater than zero, i.e.
// not transparent.
if ((px >> 24) > 0)
area++;
}
trace('number of opaque pixels (area): '+area);
Depending on your application, you might also be able to use the BitmapData.hitTest() method for your collision detection.
I believe the best you can do is to retrieve a rectangular bounding box on the Shape object. Depending on how you imported it, you may or may not have direct access to the Shape object as an instance variable; however, if you do, you can call shapeVar.transform.getBounds() or shapeVar.transform.getRect() (bounds returns a rectangle inclusive of strokes on the shape, rect does not).
I'm curious, so I'm doing a bit of research on alternate means of getting some pixel bounds. I'll edit this further if I find something useful.