patternjavaMinor
Drawing a Koch snowflake in Android
Viewed 0 times
kochdrawingandroidsnowflake
Problem
Here's my attempt to draw Koch snowflake. My initial state is a line instead of an equilateral triangle so that I am able to fit maximum detail in a mobile phone window.
My thought process was:
Code
```
public class KochView extends View {
List points = new LinkedList<>();
private int depth = 6;
public KochView(Context context) {
super(context);
}
public KochView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
protected void onDraw(final Canvas canvas) {
final int H = getHeight();
final int W = getWidth();
final Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setAlpha((int) (255 * 0.99));
paint.setStrokeWidth(1.0f);
// Adjust start/end points for the Koch 'snowflake' depending on whether we are in
// portrait...
if (H > W) {
points.add(new PointF(0.05f W, 0.01f H));
points.add(new PointF(0.05f W, 0.99f H));
}// or landscape mode...
else {
points.add(new PointF(0.01f W, 0.95f H));
points.add(new PointF(0.99f W, 0.95f H));
}
// The current algo does not draw start and end points, so we draw them manually...
drawPoint(canvas, paint, points.get(0));
drawPoint(canvas, paint, points.get(1));
doPairWise(points, new Action() {
@Override
public List exec(PointF first, PointF second) {
// Find the distance between the given two points
double r = dist(first, second);
// And the angle they subtend w.r.t the x-axis
float th = (float) (Math.atan2(second.y - first.y,
My thought process was:
- Start with two points A, B separated distance r.
- Draw three points between them, P1, P2, P3.
- P1 at distance r/3 from A on line AB.
- P2 at r/3 from the P1 at 60 degrees from the AB.
- P3 at 2*r/3 from A on line AB.
Code
```
public class KochView extends View {
List points = new LinkedList<>();
private int depth = 6;
public KochView(Context context) {
super(context);
}
public KochView(Context context, AttributeSet attributeSet) {
super(context, attributeSet);
}
@Override
protected void onDraw(final Canvas canvas) {
final int H = getHeight();
final int W = getWidth();
final Paint paint = new Paint();
paint.setColor(Color.BLACK);
paint.setAlpha((int) (255 * 0.99));
paint.setStrokeWidth(1.0f);
// Adjust start/end points for the Koch 'snowflake' depending on whether we are in
// portrait...
if (H > W) {
points.add(new PointF(0.05f W, 0.01f H));
points.add(new PointF(0.05f W, 0.99f H));
}// or landscape mode...
else {
points.add(new PointF(0.01f W, 0.95f H));
points.add(new PointF(0.99f W, 0.95f H));
}
// The current algo does not draw start and end points, so we draw them manually...
drawPoint(canvas, paint, points.get(0));
drawPoint(canvas, paint, points.get(1));
doPairWise(points, new Action() {
@Override
public List exec(PointF first, PointF second) {
// Find the distance between the given two points
double r = dist(first, second);
// And the angle they subtend w.r.t the x-axis
float th = (float) (Math.atan2(second.y - first.y,
Solution
Some minor issues, nothing serious...
-
Try to calculate the points before you draw and store them to easily redraw them (and not calculate over again).
-
What's the purpose of the
-
Additionally why do you use a generic
-
Maybe you should get away totally from that interface and declare class, because i don't see any other usage for that interface. it's for your implementation only, it's specific for your cause, hence make a class (no interface). especially when you read the documentation of the interface: ' do something with a pair of objects ' (???).
-
Why do you cast the destination of the translation of a
-
I do not know why you declare a method
Code:
-
Try to calculate the points before you draw and store them to easily redraw them (and not calculate over again).
-
What's the purpose of the
Action interface, what does exec do? A more suitable name would be really helpful (maybe IntersectingArea or addBranches - but my english is bad., do snow flakes have branches or arms or... I dont know).-
Additionally why do you use a generic
Action<> interface - it's absouletly bound to be used for Points (or PointF) and I do not see any usage in any other types of parameters.-
Maybe you should get away totally from that interface and declare class, because i don't see any other usage for that interface. it's for your implementation only, it's specific for your cause, hence make a class (no interface). especially when you read the documentation of the interface: ' do something with a pair of objects ' (???).
-
Why do you cast the destination of the translation of a
PointF into int in the method getPoint() (and why don't you rename it into translateRadial) ... you can still cast it down into int when you're drawing the point, so cast it down to float .-
I do not know why you declare a method
drawPoint() when there is no difference between the usage in onDraw() - make paint and canvas member vairables and change the method into:Code:
private void drawPoint(PointF p) {
canvas.drawPoint(point.x, point.y, paint); //canvas is member, paint is member
}Code Snippets
private void drawPoint(PointF p) {
canvas.drawPoint(point.x, point.y, paint); //canvas is member, paint is member
}Context
StackExchange Code Review Q#146393, answer score: 2
Revisions (0)
No revisions yet.