How to create custom shape in java - java

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.

Related

How do I prevent a cast or making child specific methods in the interface in java?

I have a problem keeping my code maintainable.
In my problem I have defined a 'RenderableShape' that is the parent interface of both 2D and 3D shapes (those two are interfaces).
I have a Renderer class that 'asks' a RenderableShape for the data to render.
A 3D shape should return some mathematical formula or object wrapped around that and a 2D shape returns all its 2D shapes it consists of (triangles, circles etc.).
Obviously 'RenderableShape' cannot return both types two the renderer.
I could make two different methods, but that would force all implementations to implement a useless method.
The renderer can also ask for the shape what kind it is, but you would need a cast afterwards, which should not only be unnecessary, but would also be too slow to use in rendering.
Furthermore, the rendering code should not be in shapes themselves, since I would like to have all rendering code in a renderer, to allow for different renderer types (Z-Buffer, raytracer etc.)
What would be a maintainable and preverably efficient approach to this problem?
What would be a maintainable and preverably efficient approach to this problem?
One of the OOP principles which should be applied here is tell, don't ask!
Pass the renderer to the RenderableShape and have it draw itself to the renderer.
First of all, you should not even think about "removing" a method from an interface. If you can call foo() on the super class, the Liskov substitution principle states that you need that foo() must exist on the derived classes, too. Anything else is a clear violation of how OOP is supposed to work.
So, you should follow the answer that was already given. Don't ask a shape for something that tells the renderer what to do - but instead enable each shape to render itself (by passing the renderer to the shape).
Try to decompose your task further, what is shapes? it is set of curves and lines in certain positions
of display. How about to make something like simple api to do that? Make render to write lines, curves,
dots, etc.
interface Render {
renderLine(Formula formula);
renderCurve(Formula formula);
renderDot(Formula formula);
}
after that create Shape that get Render instance and write himself through this api.
Shape knows all about what amount of dots, lines etc. need to write himself. Formula is interface that
present mathematic formula. When you need more complex objects further make Render to render
simple triangles, squares, etc.

How to make vector line selectable?

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!

How would i go about filling a triangle made by connecting 3 points

im interested i just finished writing a program and one of the functions that has been implemented is drawing a line with a triangle at the end (forming an arrow). How would i go about filling the inside of the triangle?
Take a look at the fillPolygon method of the Graphics class. There's also a version that doesn't require you to make a Polygon, instead accepting arrays with the coordinates. If you've been drawing the lines separately until now instead of as a polygon, it shouldn't be too hard to switch to one of these methods. Just use the endpoint coordinates you've already got.
In a paint method, call Graphics.fillPolygon, or use Graphics2D.fill(Shape).

How to animate Rectangle on a Path2D object in Graphics2D context

I have just started learning basics about Graphics2D class, So far I am able to draw different objects and implements ActionListener to actually move them on screen by onKeyPress. So far so good, While I thought of doing something more complicated. I want to give a path to my object and animate it on that particular path only.
Something like, I will draw a line on sky and a plane should stick with that drawn line and keep it self to fly on that particular line. Now is it possible?
I don't need any sort of code, But few different method or ideas will let me get started working on this. A visualise elaboration of my idea is as below.
Start Point :
End Point :
Now as shown above, my yellow box(in future plane) should stick with given path while animating(path grey line)
My research so far,
I have searched my buzz words such as path in java, and found Path2D and GeneralPath classes, Does anyone know if I can use that to solve this.
Thanks
Great !
It reminds me of my first steps in IT. How much I enjoyed all this simple math stuff but that make things move on screen. :)
What you need is actually a linear interpolation . There are other sorts of interpolation and some api offer a nice encapsulation for the concept but here is the main idea, and you will quite often need this stuff :
you must rewrite your path
y = f (x )
as a function of time :
at time 0 the item will be on start position, at time 1 it will reach the end. And then you increment time (t) as you wish (0.001 every ms for instance).
So here is the formula for a simple linear path :
x = xstart + (xend-xstart) * t
y = ystart + (yend-ystart) * t
when t varies, you object will just move linearly along the path, linearly has speed will be constant on all the path. You could imagine some kind of gravtity attraction at end for instance, this would be modeled by a quadratic acceleration (t^2 instead of t) ...
Regards,
Stephane
First, make the ability to move from point a to point b. This is done with simple algebra.
Second, make the ability to take a path and translate it into points. Then when you're going to do curves, you're really just moving from point to point to point along that curve.
This is the most elementary way to do it and works for most instances.
What your talking about is simple 2D graphics and sprites. If that is all you need then for Java take a look at Java 2D Sprites If your leaning more towards or will eventually go with camera perspectives and wanting to view the animation from diferent angles the go with Java 3D from the OpenSource Java 3D.org. Either way what you want is a simple translating of the object along a line, pretty simple in either 2D or 3D.
You can try going trough the code of my open source college project - LANSim. It's code is available in Code menu. It does similar to what you are trying to do.

Drawing a line connecting two rectangles

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

Categories

Resources