I'm making a project for college, where I have to make my own primitive vector editor, and I have two questions:
Is it right to make vector line object by saving it's start point coordinates, end point coordinates, color and width of points, which it will consist of? Point is also my class, which is drawn on JPanel.
If it is right, how can I make this line selectable? The only thing I can think of is to check mouse coordinates to be inside of line width.
I also have a restriction not to use any standard functions for drawing lines, splines, etc.
Yes that's right. Or you could represent it in polar coordinates
the best thing to do is actually turn your line into an Area, which implements Shape and thus contains, which is the method you want. Area is a great abstraction because it can represent any shape but everything gets manipulated in the same way.
You can use Line2D Shape. To check selection you can gt stroked Shape from BasicStroke and check whether the stroked Shape contains clicked point.
To Point 1: You also need to save the direction of the vector.
To Point 2: There are some frameworks like GEF which do the job for you. Here you have to change your model. You need two classes: Point and Connection
You can use a class Vector if you have one with start and end Point for do it if you want.
You can have a method like that:
private static Shape generateVector(Point start, Point end)
In this method you can use one object of ´Area´ for build the vector, with Line2D. Tree lines if you want an arrow.
Or you can use a GeneralPath for build it.
For select a particular vector with the mouse, you can get the coordinates, with getX() and getY() on the MouseEvent and ask in the shape object with method contains and repaint with other color.
Good luck!
Related
Can anyone share a code how to draw a rectangle like this?
(not vertical, not horizontal, somewhere between)
Because as I see you can only specify 4 ints to function DrawRect(), not 4 points.
The area of rectangle must be sensitive to touch (I use Contains() method)
As I tried, Matrix and Rotate() update only graphics, the rect's area remains the same it was
After transforming as #fortran suggested, you can use one of the Matrix.mapPoints overloads to find out what the new corners of your rectangle are. You'll probably have to find some fancy math and do hit testing yourself. Might be easier to call Matrix.mapPoints() on the inverse of the transformation used to draw the rectangle, passing the touched coordinates, and then hit test on the original rectangle.
Push a rotation transformation, draw the rectangle, pop it.
http://developer.android.com/reference/android/graphics/Canvas.html#rotate%28float,%20float,%20float%29
I found solution - the easiest way is to use Path class, make a free-turned rectangle by points and then create a region method, which has function Contains()
No need for math and hard work, pretty and easy.
I am doing some java games, and I figure it would be cool if the game is made without importing images. Therefore I need to create custom shapes and hand it to Graphics object to draw. The major character in my game will be a dango which is much like a slime, composing from a imperfect circle and two vertical lines as eyes. I should be able to construct dango by given a parameter indicating size. Also, it will be better if I can modify the position of the eyes, or the bottom curve to present the interaction with the floor. Further more, I would be glad if I can fill it with color and give it some texture or something. But all things start from a circle and two lines.
I checked some APIs including Shape, GeneralPath, PathIterator, Area, Ellipse, and some source code. I learnt how to use GeneralPath to draw straight line, quadratic curve, and bezier curve. But still I don't know how to implement my custom shape. I found this question in stackoverflow but no good answer is posted.
In case someone just read the title and skips the content of this question, I shall emphasize that this question is about create the custom shape, which means to implement the 'Shape' interface. Not just to draw a shape.
So after a day of research, I finally did it. For anyone who holds the same problem with me, I recommend you to do what I have done.
First, refer to the java api source code, here I chose the source code of Ellipse2D.class. Following the source code, you may ignore the 2 inner static class Ellipse2D.Double, Ellipse2D.Float, they are not so important at this point.
To implement the Shape interface, the most important method is
public PathIterator getPathIterator(AffineTransform at) {
return new EllipseIterator(this, at);
}
this method is called by paintComponent to get a PathIterator to draw. So as what the source code does, you may create your own ShapeIterator.
Then the source code of EllipseIterator. As you can see, there are 4 methods (excluding the constructor and the duplicate). You may leave getWindingRule() for furthur research. While isDone() and next() are rather simple to understand.
Then let's focus on public int currentSegment(float[] args).
The return values is int, which should be the static final int fields: SEG_CLOSE, SEG_CUBICTO, etc.. They give instructions on drawing your shape. SEG_MOVE will move the start point, SEG_LINETO will draw a straight line from start point to end point. There are few more like the quatratic curve and Bezier curve, you may check the details at java api.
The argument float[] args should also be regarded as return value statement. It delivers the parameters for the instructions above. For SEG_MOVETO, SEG_LINETO, you need 2 params, so modify args[0] and args[1] ( x and y). For SEG_QUADTO, you need 4 params, and SEG_CUBICTO needs 6.
Carefully follows the source code, it won't be hard to create a shape. I haven't complete all the methods in Shape interface yet, but the shape can already be drawn by a g2d instance.
I currently have an arraylist of points from a freehand drawing on a canvas. I was wondering if there is a simple algorithm to detect if that shape represents a circle.I have already researched this a little and the main items I am pointed at are either the Hough transform or having bitmap images but both of these seem a little over the top for what I need it for. Any pointers to algorithms or implementation would be very helpful.
thanks in advance sansoms,
If I interpret your question correctly, you want to know if all the points are on a circle.
As illustrated in the picture, we pick three points A, B, C from the list and compute the origin O of the presumed circle. By checking the distance between O and each point from the list, we can conclude whether these points are on a circle.
If you do not know what the user wanted to draw (e.g., a circle, an ellipse, a line, or a rectangle), you could use some basic optimization algorithm to find the shape best matching the hand-drawn points.
for each basic shape (oval, rectangle, triangle, line, etc.), create a random instance of that shape and measure the error w.r.t. the given points
optimize each of the shapes (individually) until you have the oval best matching the given points, the rectangle best matching the points, the best triangle, etc.
pick the shape that has the lowest error and draw it
Maybe this answer can give you some ideas: https://stackoverflow.com/a/940041/12860
In short: calculate the second derivative. If it is quite constand, it is probably a circle.
Reading your comment, an easier method to draw a circle is for the user to click the center point, then drag the radius of the circle. It's a lot less calculation, and easier for the user to draw.
You can do the same thing with a rectangle, or any other convex polygon.
I wish to create a dynamic outline to a Shape (AWT) by adding objects (with draw functions) to appropriate positions on screen along the shape's perimeter. I want a roughly even distance between each object. (An alternative approach to the same affect will be fine.)
How might I acquire the locations for these objects? I know shapes have a path iterator, but I have no idea how to use it.
You might look at a library such as the one described in A Shape Diagram Editor.
If you want to experiment, GraphPanel is a simple object drawing program that features moveable, resizable, colored nodes connected by edges. If the nodes were a little smaller, they'd be moveable points on a Shape that can be iterated as shown here for Polygon.
Addendum: I want a roughly even distance between each object.
The class Node exposes a number of static methods that operate on a List<Node> such as selected. Existing implementations serve, for example, to translate or resize multiple selections as a unit. Functions for Align and Distribute could be implemented similarly. I'd look at LayoutManger as an example for the latter.
Use FlatteningPathIterator to get points for Shape's path.
Also you can use BasicStroke's method
public Shape createStrokedShape(Shape s)
to get Shape's outline with desire width.
I am making my own class diagram app in Swing/AWT but i stopped at this functionality:
I want to draw a line between the Class rectangle that already selected and to the target Class rectangle, but line has a feature which is whenever i move one of the rectangles the line that join them get bend in a straight fashion following the moving rectangle , i hope the following picture demonstrate what i want to achieve:
A general guideline or a sample code is highly appreciated
I don't know Java, but the steps you could follow are these:
Find the middle of each line of the rectangles (should be easy, just avarage x1+x2 and y1+y2)
Determine the edges that are closest to each other using Pythagoras formula on the points you got in the previous step.
Start drawing a line starting at xa,ya (first point you got in the step above), and draw it in the direction away from the rectangle. You should know this direction, because you can know the line segment this point is on.
Do the same for xb,yb (point on the second rectangle). If the lines are in opposite directions, you should draw them to halfway xa-xb or ya-yb (depending on if you're drawing horizontally or vertically). If they are perpendicular (is that the right word?) you should draw them to the point where they cross, so you draw the line from xa,ya to xa,yb or xa,ya to xb, ya, depending if you draw the horizontal or vertical line.
There should be some additional check to see if the rectangles overlap. You should not draw lines in the same direction for example. Maybe it would suffice for you to draw just a diagonal line between the two points in those cases where you cannot determine how to draw these straight lines.
For the implementation you could build a line class that uses the observer pattern to listen to the two rectangles it follows, so it can update itself whenever one of them moves or resizes.
http://java-sl.com/connector.html
Hope this helps.
Try with observer pattern. All lines that are connected with a moving object should be notified with new position of the object and 'bent' properly. Of course, first implement some logic that will connect 2 objects.
try creating a class named "ConnectingLine" or similar. this class will then have several segments (that's the name of these line parts in dia, which is currently my favorite uml modeling tool) which will be calculated one by one. you'll have a sepaparate class for this of course ;) called maybe "LineSegment". i think this should make it easier for you to perform the mathematical calculations required to perform this task.
this could also enable making segments "auto routed or not" easy d(^_^)b