I'm using Java's QuadCurve2D and I'd like to show an anchor point exactly half way across this curve. I have code like this:
Point anchor = anchor();
if (showArcHandle) {
Ellipse2D.Float e = new Ellipse2D.Float(anchor.x-ANCHOR_RADIUS, anchor.y-ANCHOR_RADIUS, 2*ANCHOR_RADIUS, 2*ANCHOR_RADIUS);
g2.draw(e);
}
but this was assuming that the anchor point was the same as the control point in the QuadCurve API.
As my anchor point is always half way across the curve, and the curve is always symmetric, is there a way to find this point, which should rest on the line?
I hope that makes sense, if anything needs clarifying, please ask.
Thanks
Don't know for sure ... but QuadCurve2D.subdivide(QuadCurve2D,QuadCurve2D) mentiones 2 halfs.
Related
ive been looking for a while and cannot find solution
so I am trying to find a point on a polyline that is either a certain distance toward the opposite point or away from the main point.(I have pictures) if you are familiar with celestial navigation this is called the intercept method. so here is the almost working code.
double distance = ap.distanceToAsDouble(gp)*0.00053996;
double convert = nauticalMiles;
double t = convert / distance;
double actlon = ((1 - t)*ap.getLongitude() + t*gp.getLongitude());
double actlat = ((1 - t)*ap.getLatitude() + t*gp.getLatitude());
bear = ap.bearingTo(new GeoPoint(actlat,actlon));
actual = ap.destinationPoint(nauticalMiles/0.00053996,bear);
so "ap" is the point that the point I am trying to find will be (nauticalMiles) "away" or "toward" the "gp" and they are correct so "bear" is the angle kind of from ap to gp that almost works completely. "actual" is the point I am trying to find. here is an image of how this works out.
as you can see th actual point is toward the gp point from the ap point denoted with the yellow polyline. BUT!!!! if you look at the picture the yellow line is not exactly on the red line so I think that it is off a bit. so I tried to do
bear = ap.bearingTo(gp);
actual = ap.destinationPoint(nauticalMiles/0.00053996,bear);
instead doing that whole calculation that was in the code sample previously which should work but I am getting this
which is totally off it is not on the line. so for right now I am sticking with the first approach because it is relatively accurate but that is why I am asking this question. What calculation could I do to make the yellow line exactly on the red line? I am trying to get the most accurate calculation that I can get. thank you for your time.
So I'm programming a recursive program that is supposed to draw Koch's snowflake using OpenGL, and I've got the program basically working except one tiny issue. The deeper the recursion, the weirder 2 particular vertices get. Pictures at the bottom.
EDIT: I don't really care about the OpenGL aspect, I've got that part down. If you don't know OpenGL, all that the glVertex does is draw a line between the two vertices specified in the 2 method calls. Pretend its drawLine(v1,v2). Same difference.
I suspect that my method for finding points is to blame, but I can't find anything that looks incorrect.
I'm following the basically standard drawing method, here are the relevant code snips
(V is for vertex V1 is the bottom left corner, v2 is the bottom right corner, v3 is the top corner):
double dir = Math.PI;
recurse(V2,V1,n);
dir=Math.PI/3;
recurse(V1,V3,n);
dir= (5./3.)* Math.PI ;
recurse(V3,V2,n);
Recursive method:
public void recurse(Point2D v1, Point2D v2, int n){
double newLength = v1.distance(v2)/3.;
if(n == 0){
gl.glVertex2d(v1.getX(),v1.getY());
gl.glVertex2d(v2.getX(),v2.getY());
}else{
Point2D p1 = getPointViaRotation(v1, dir, newLength);
recurse(v1,p1,n-1);
dir+=(Math.PI/3.);
Point2D p2 = getPointViaRotation(p1,dir,newLength);
recurse(p1,p2,n-1);
dir-=(Math.PI*(2./3.));
Point2D p3 = getPointViaRotation(p2, dir, newLength);
recurse(p2,p3,n-1);
dir+=(Math.PI/3.);
recurse(p3,v2,n-1);
}
}
I really suspect my math is the problem, but this looks correct to me:
public static Point2D getPointViaRotation(Point2D p1, double rotation, double length){
double xLength = length * Math.cos(rotation);
double yLength = length * Math.sin(rotation);
return new Point2D.Double(xLength + p1.getX(), yLength + p1.getY());
}
N = 0 (All is well):
N = 1 (Perhaps a little bendy, maybe)
N = 5 (WAT)
I can't see any obvious problem code-wise. I do however have a theory about what happens.
It seems like all points in the graph are based on the locations of the points that came before it. As such, any rounding errors that occurs during this process eventually start accumulating, eventually ending with it going haywire and being way off.
What I would do for starters is calculating the start and end points of each segment before recursing, as to limit the impact of the rounding errors of the inner calls.
One thing about Koch's snowflake is, that the algorithm will lead to a rounding issue one time (it is recursive and all rounding errors add up). The trick is, to keep it going as long as possible. There're three things you can do:
If you want to get more detailed, the only way is to expand the possibilities of Double. You will need to use your own range of coordinates and transform them, every time you actually paint on the screen, to screen coordinates. Your own coordinates should zoom and show the last recursion step (the last triangle) in a coordination system of e.g. 100x100. Then calculate the three new triangles on top of that, transform into screen coordinates and paint.
The line dir=Math.PI/3; divides by 3 instead of (double) 3. Add the . after the 3
Make sure you use Point2D.Double anywhere. Your code should do so, but I would explicitely write it everywhere.
You won the game, when you still have a nice snowflake but get a Stackoverflow.
So, it turns out I am the dumbest man alive.
Thanks everyone for trying, I appreciate the help.
This code is meant to handle an equilateral triangle, its very specific about that (You can tell by the angles).
I put in a triangle with the height equal to the base (not equilateral). When I fixed the input triangle, everything works great.
I am trying to test if a point lies within a circle and if the point is on the perimeter, it should be included in the results. However, Java's contains() implementation uses less than instead of less than or equal to. For example consider this snippet:
Ellipse2D.Double circle = new Ellipse2D.Double(0, 0, 100, 100);
System.out.println(circle.contains(50, 0));
System.out.println(circle.contains(50, 100));
System.out.println(circle.contains(0, 50));
System.out.println(circle.contains(100, 50));
System.out.println(circle.contains(50, 50));
This prints the following:
false
false
false
false
true
How can I achieve a value of true for all of those cases?
You have to decide what kind of tolerance your method will use. While your example uses points that are expressible in floating point, there are many points along the border of the ellipse which will not be, and so deciding whether a point is "on the border" isn't clear-cut. If you don't much care, then I would suggest making the ellipse slightly "bigger" than you actually want and using the built-in contains() method.
If you want to write your own method, it's as simple as taking the formula for an ellipse, plugging in the X and Y values of the point you wish to test, and observing the result:
bool isInsideOfOrOnBorderOfEllipse = ((x*x)/(a*a) + (y*y)/(b*b)) <= 1;
Note that this still runs into the problem of non-representable points, so some points that you think should be "on the border" won't be.
Update: Given that you're just using the built-in ellipse object (and thus specifying height/width rather than the general ellipse parameters) it would be worthwhile to have a look at the source for contains() here: http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/ffa98eed5766/src/share/classes/java/awt/geom/Ellipse2D.java
Derive a new class, and then override contains(). In the overridden version, just copy the code, except use <= instead of < and you should be good.
You could use the method intersects. As javadoc says: Tests if the interior of this Ellipse2D intersects the interior of a specified rectangular area. Although it is not a circle (best representation of a tolerance around a point) works pretty well
This snippet should work for any x, y you want to check:
int size = 2;
...
ellipse.intersects(x - (size/2), y - (size/2), size, size);
It is just a rectangle around the point of interest. More size, nore tolerance
Maybe getDistance() can help you here? Points on the prerimeter should return 0.
I've just tried to write "line" code to visualize a simple math;
Here it is
Ploygon polygon=new Ploygon();
int x,y;
ploygon.addPoint(0,0);
polygon.addPoint(width,height);
g.drawPolygon(polygon);
The code gives y=x effect;
OK... it is quite simple code; But the thing I am interested to get is points each N pixels during the statement period as {x0,y0}{0,0} and {x1,y1} {width,height} and that is the problem :(
The polygon xpoints array is not handy because it may contain just the same points which were added when addPoint(x,y) method was invoked; so in my case there just two added points which are connected by Polygon but what about all the rest points which stay between these points {x0,y0}{0,0} and {x1,y1} {width,height} ? How to get them?
For example. Coming back to the previous snippet how to find out what point x,y value is when (height%N)=0 etc?
Is there the most optimal way?
Thanks
What you have to realise here is that you are no longer working with pixels/coordinates per se, but you are working with vectors. You'd get much the same image from a polygon contained the coordinates (-500,-500) and (500,500) which is drawn onto a Graphics object which represents the (clipped) area from (0,0) in the bottom left to (100,100) in the bottom right. (ignoring for now that the actual coordinate system of Graphics has an inverted y-axis).
Therefore you have to solve this in a more back-to-basic's Math way rather than a “read the pixels” way. Unless you just want to determine if a given point is in the shape (for which the Shape interface offers a built-in method), you would be looking at calculating the slope of a line and determining functions which represent your line. For instance continuing from the example you have two points (-500,-500) and (500,500) which gives a slope of 1000/1000 = 1. So you could rewrite that function in terms of your x-coordinates as f(x) = -500 + (x + 500). Then if you want to know if the point (100,200) is on that line all you need to do is calculate f(100) and see that it isn't.
Getting back to your example, finding points which match a predicate (height%N =0), we'd be looking for f(x) == 0 mod N and so 'all' you'd need to do is solve the equation for x.
I have been trying to find a collision avoidance example that I can adapt and use for a game I am working on. It will be used to model a skier's movements to avoid trees on the hill. I am basing the movement off of Steering Behaviors for Autonomous Characters and there are a lot of good examples for path following and flocking, but I can't find any good ones for collision avoidance. The Nature of Code website had awesome tutorials for steering but seemed to cover everything but obstacle avoidance.
I converted the code from here but it doesn't work as well as it should because collisions are found by projecting the obstacles center onto the velocity vector without taking into account when the obstacles center may be outside the limits of collision but the circle is still colliding. Here is the code I adapted (written in Processing (Java based)).
// Method to update location
void update() {
// Update velocity
vel.add(acc);
// Limit speed
vel.limit(maxspeed);
loc.add(vel);
// Reset accelertion to 0 each cycle
acc.mult(0);
}
void obstacleAvoid() {
float checkLength = 30*vel.mag();
PVector forward,diff,ray,projection,force;
float dotProd,dis;
forward = vel.get();
forward.normalize();
ray = forward.get();
ray.mult(checkLength);
for ( int i = 0; i < obs.size(); i++ ) {
Obstacle ob = (Obstacle)obs.get(i);
diff = ob.pos.get();
diff.sub(loc);
PVector temp2 = forward.get();
temp2.mult(ob.r);
diff.sub(temp2);
dotProd = diff.dot(forward);
if ( dotProd > 0 ) {
projection = forward.get();
projection.mult(dotProd);
dis = PVector.dist(projection,diff);
if ( (dis < (ob.r + r)) && (projection.mag() < ray.mag()) ) {
ob.hit = true;
force = forward.get();
force.mult(maxforce);
if ( sign(diff,vel) == -1 ) { //CCW
force.set(force.y,-force.x,0);
}
else { //CW
force.set(-force.y,force.x,0);
}
force.mult(1-(projection.mag())/ray.mag());
force.limit(maxforce);
acc.add(force);
}
}
}
}
So to help me I was wondering if anyone knew of any complete examples of collision avoidance that follow the Steering Behaviors for Autonomous Characters way of doing things better. This Site is the example applet for the paper and is the exact example I wish I could see the code for. Sadly there is no code to come with it and I tried decompiling it but it just showed the main class so that wasn't very helpful. If someone has the code for this example or something like it, or a tutorial, I would appreciate it a lot.
Craig Reynolds cannot release the source code for the applets you're interested in. Similar source code is available in c++ at OpenSteer, which is maintained by Reynolds. Christian Schnellhammer and Thomas Feilkas worked to expand Reynolds original paper. Their paper is translated into english and contains a section on obstacle avoidance. The source code for their work is available in Java. However, I think Shiffman's code is a great starting point, and it sounds like you're pretty close to what you want already
One of my first Processing programs modified the Boids example to simulate a zombie apocalypse. Triangles chased circles that were avoiding them. Each survivor checks for other zombies in their vision, and averages the location vectors of threats in a function, PVector panic(ArrayList infected). After that, it was a matter of weighting the new vector negatively and adding it to the survivor's current vector like any other force. Something like:
void flock(ArrayList uninfected, ArrayList infected) {
PVector sep = separate(uninfected); // Separation
PVector ali = align(uninfected); // Alignment
PVector coh = cohesion(uninfected); // Cohesion
PVector pan = panic(infected); // Panic
// Arbitrarily weight these forces
sep.mult(4.0);
ali.mult(1.0);
coh.mult(2.0);
pan.mult(-3.0);
// Add the force vectors to acceleration
acc.add(sep);
acc.add(ali);
acc.add(coh);
acc.add(pan);
}
If your skier is successfully detecting the obstacles, then avoidance is the problem. Adding a stronger weight to the avoidance vector, increasing the radius the skier can 'see' to interact with objects, or even adding a method to the object that returns the location of the closest point to the skier could solve your problem. You could also add deceleration based on the distance from the skier to the nearest obstacle in front it.
Remember that even the applet you're interested in does not perfectly avoid obstacles. My solution may not be exactly what is happening in the applet, but by playing around with the forces determining you skier's direction, you can achieve a very similar (and possibly better) effect.
Checkout this link on NEHE game development site:
In this tutorial you will learn the
basics of collision detection,
collision response, and physically
based modelling effects. This tutorial
concentrates more on how collision
detection works than on the actual
code, although all of the important
code is explained.
http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=30
It is done using c++ and win32 API. Although you will find a link for Java Port using JOGL.
Also
The Source code for http://www.red3d.com/cwr/steer/ is available here http://opensteer.sourceforge.net/ though in c++. Have you checked it??