integer lattice pairs within a circle c# - c#

I am having trouble trying to write a method (in c#) that returns all of the integer lattice pairs within a circle of a given radius at a specific offset. I found this article https://en.wikipedia.org/wiki/Gauss_circle_problem but unfortunately it seems more interested in calculating the number of lattice pairs rather than identifying each individual lattice pair.
I am also having issues understanding some of the math terminology/symbols as my math is sadly somewhat lacking, so code examples or detailed explanations would be super helpful if possible.
my plan so far is to just check each integer value combination from the radius to negative radius and then simply check the distance to the origin, before applying the offset to the vectors that are within range.
Am i on the right track with this, or is there a more optimized way to achieve this?
example stub:
public class CircleTest ()
{
public List<Vector2>GetContainedIntegerVectors(float radius, Vector2 centerPosition)
{
//math goes here
}
}
Simple Vector2 class
public class Vector2 ()
{
public float x {get; set;}
public float y {get; set;}
}
Thanks!

For my understanding you are on the right track, but there are some optimizations possible:
use the System.Windows.Vector class from C# instead of your own
you only have to calculate the points of a quarter of the circle, eg for x>0 and y>=0 and mirror the rest (plus include centerpoint).
here a possible implementation:
List<Vector> tmpList = new List<Vector();
List<Vector> list = new List<Vector();
double rSquared=r*r; // using sqared reduces execution time (no square root needed)
for(int x=1; x<=r; x++)
for(int y=0; y<=r; y++) {
Vector v = new Vector(x,y);
if(v.LengthSquared<=rSquared)
tmpList.Add(v);
else
break;
}
list.Add(centerVector);
foreach(Vector v in tmpList) {
Vector vMirr = new Vector(v.X, -1*v.Y);
list.Add(Vector.Add(centerVector, v));
list.Add(Vector.Add(centerVector, v.Negate()));
list.Add(Vector.Add(centerVector, vMirr));
list.Add(Vector.Add(centerVector, vMirr.Negate));
}

public List&ltVector2&gtGetContainedVectors(int radius, Vector2 offset)
{
List<Vector2> returnValues = new List&ltVector2&gt();
for (int x = radius; x > -radius; x--)
{
for (int y = radius; y > -radius; y--)
{
if(Vector2.Distance(new Vector2(x,y), Vector2.zero) <= radius)
{
returnValues.Add(new Vector2(x + offset.x, y + offset.y));
}
}
}
return returnValues;
}

Related

C# - Select Diamond Shaped radius based on coordinates within list of custom class

Gonna be honest, I probably have a bad title there, so allow me to explain. (Title suggestions are welcome!)
First and foremost, I have a 'List' aptly named TileList. Tile is a class that contains a few variables, but the important ones are these two: public int xCoor and public int yCoor.
TileList is automatically filled by an outside function. In this case, it's filled with exactly 100 instances of the Tile class, each with a different set of xCoor and yCoor- with xCoors from 0 to 9 as well as yCoors from 0 to 9, basically simulating a 10x10 grid.
As it's filled by an outside function, it's not always 10x10, it can also be 5x15 or 20x20 and so on.
I have a function that grabs a specific tile, named FindTile- that one works perfectly thus far...
But now I need one that selects a diamond shape from the grid, based on a starting point and a radius. And my own attempt, the FindDiamond function.. is very messy and takes forever to load.. and in fact sometimes doesn't even work.
This is basically what I want to do: Grid example
Code is down below:
public class Tile
{
public int xCoor;
public int yCoor;
//more variables
}
public class TileFinder
{
public List<Tile> TileList = new List<Tile>();
//Give back tiles when generated
public void SaveGeneratedTiles(List<Tile> Save)
{
TileList = Save;
}
public Tile FindTile(int tileX, int tileY)
{
for (int i = 1; i < TileList.Count; i++)
{
if (TileList[i].xCoor == tileX && TileList[i].yCoor == tileY)
{
return TileList[i];
}
}
return null;
}
public List<Tile> FindDiamond(int tileX, int tileY, int radius)
{
List<Tile> ReturnList = new List<Tile>();
for (int r = 0; r <= radius; r++)
{
int curx = tileX + r;
int cury = tileY;
if (curx == tileX) { FindTile(curx, cury); }
else
{
while (curx != -r)
{
curx--;
cury--;
ReturnList.Add(FindTile(curx, cury));
}
while (cury != -r)
{
curx++;
cury--;
ReturnList.Add(FindTile(curx, cury));
}
while (curx != r)
{
curx++;
cury++;
ReturnList.Add(FindTile(curx, cury));
}
while (curx != -r)
{
curx--;
cury++;
ReturnList.Add(FindTile(curx, cury));
}
}
}
return ReturnList;
}
}
Frankly, I'm looking for a better way to make this work, that does end in a returned List at the end.. Other parts of my code function off of this, which in fact may also not be the best way, but I'm still blundering my way through this. :)
TL;DR I'm trying to emulate something like Advance Wars, and I need the diamond shape to select ranges for fog of war vision, indirect attacks, etc.
First and foremost, to represent a grid, a 2d array would be a much better choice than a list. A list would work as well but is redundant.
If you know the grid to only contain 10x10 tiles, and you can guarantee their order, finding a specific tile by x and y coordinates should be an o(1) operation, not an o(n) linear search like you currently have in FindTile. Also in that function, why are you starting from index 1 and not 0?
To create a diamond pattern should be very straightforward.
Start with the row (Y coordinate) of the starting point. From there go radius steps backward on the X and radius steps forward on the X. For radius rows below and above the starting point, do the same thing, but for each of those rows, decrease radius by 1.
Something like this? Haven't tested it.
public List<Tile> FindDiamond(int tileX, int tileY, int radius)
{
List<Tile> ReturnList = new List<Tile>();
for (int x = 0; x < radius; x++)
{
for (int y = 0; y < radius-x; y++)
{
ReturnList.Add(FindTile(tileX + x, tileY + y));
ReturnList.Add(FindTile(tileX + x, tileY - y));
ReturnList.Add(FindTile(tileX - x, tileY + y));
ReturnList.Add(FindTile(tileX - x, tileY - y));
}
}
return ReturnList;
}
The "diamond" can be represented as a circle with distances measured using Manhattan Distance.
Manhattan Distance is measured by the sum of absolute differences of the X and Y coordinates of the points in question.
static int ManhattanDistance(int x1, int y1, int x2, int y2) {
return Math.Abs(x1 - x2) + Math.Abs(y1 - y2)
}
This simplifies your FindDiamond method to a single line (if using LINQ).
List<Tile> FindDiamond(int centerX, int centerY, int radius) {
return TileList.Where(tile => ManhattanDistance(tile.xCoor, tile.yCoor, tileX, tileY) <= radius).ToList();
}
FindTile can also be simplified to a one-liner using LINQ:
Tile FindTile(int tileX, int tileY) {
return TileList.FirstOrDefault(tile => tile.xCoor == tileX && tile.yCoor = tileY);
}
If, however you cannot use LINQ for some reason, just loop through TileList in FindDiamond and return all the Tile satisfying the clause inside Where.
I suggest that you improve your design for efficiency though, like #Rotem says. It'll make your code more efficient and quick. FindTile is a method I can imagine being called hundreds of times each frame, so it's best to make the code as efficient as possible. Even with variable width and height the method stated by #Rotem will work.
I also recommend that you create your own Point structure for easy storage and using blah.X and blah.Y instead of using blahX and blahY everywhere. It can also include useful helpers like ManhattanDistance and so on.
A sample Point structure:
struct Point {
public int X, Y;
public int ManhattanDistance(Point other) {
return Point.ManhattanDistance(this, other);
}
public static int ManhattanDistance(Point a, Point b) {
return Math.Abs(a.X- b.X) + Math.Abs(a.Y - b.Y)
}
}

How can I rotate a 3D array in c#?

I have a binary object in a 3d array located in the origin (0,0,0). I need rotate this object dinamically in z axis. How can I rotate that multidimensional array with no fixed size in any angle?
I have created a 3d Point Class:
public class Point3
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
I'm thinking in do a foreach in each point and rotate it:
foreach (Point3 p in listPoint3)
{
RotatePoint(p, angle);
}
Any suggestion?
You colud create a routine to rotate each point using the parametric equation for rotate the 3d object.
x' = x*cos(o)-y*sin(o)
y' = y*sin(o)-y*cos(o)
z' = z
private Point3 RotatePoint(Point3 p0, int angle)
{
Point3 p = new Point3()
{
X = p0.X * Math.Cos(angle) - p0.Y * Math.Sin(angle),
Y = p0.X * Math.Sin(angle) + p0.Y * Math.Cos(angle),
Z = p0.Z,
};
return p;
}
You need to know what axis you want to rotate on. But if this is only a question where to look at. (namespace System.Windows.Media.Media3D)
You can try this:
double angle = 45;
RotateTransform3D zrotation = new RotateTransform3D(new AxisAngleRotation3D(
new Vector3D(0, 0, 1), angle));
foreach (Point3D p in listPoint3)
{
Point3D rotatedPoint = zrotation.Transform(p);
}
You should use the build-in Point3D
Also if you want to Stack those: (multiple transforms)
double zAngle = 45;
double xAngle = 10;
Transform3DGroup group = new Transform3DGroup();
group.Children.Add( new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), xAngle)));
group.Children.Add( new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 0, 1), zAngle)));
foreach (Point3D p in listPoint3)
{
Point3D rotatedPoint = group.Transform(p);
}
So you have a "monochrome object" which is stored like a 3D bitmap which you want to rotate around the Z axis. You must first understand that after a number of rotations you will end up with optical aberrations caused by the fact that you're using an array index which is a natural number to represent a coordinate of an object's component.
Upon rotation, any integer value will most likely become an irrational number. The fact that traditionally (not talking about special programs and frameworks) people store approximations of irrational numbers in double or float or decimal variables (which can only store a small subset of the rational numbers set) is nothing compared to the approximation of an irrational number by storing it in an integer (an array index).
Furthermore, even if that quality loss if of no big importance in the case of your application, you must be sure you understand that mathematically speaking, after a number of rotations, your 3d shape will be trimmed by the cylinder which is inscribed in the original parallelepiped, alongside the Z axis.
It goes like this. You said you already made a class called Point3:
public class Point3 {
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }
}
Maybe you should follow #Jeroen van Langen's advice and use a standard class, if such a class already exists. The benefit would be that if someone out there already built or will ever build a library which uses that class you can start using the library right away.
But that's not so important right now.
#Alpert already gave a great C# code for rotating a point around the oZ axis. This is n "extension method" adaption of that code:
public static class RotationHelpers {
public static Point3 RotatePoint(this Point3 point, int angle) {
var result = new Point3() {
X = point.X * Math.Cos(angle) - point.Y * Math.Sin(angle),
Y = point.X * Math.Sin(angle) + point.Y * Math.Cos(angle),
Z = point.Z,
};
return result;
}
...
}
You can go even further and make an extension method which rotates a sequence of points around the oZ axis:
public static class RotationHelpers {
...
public static IEnumerable<Point3> RotatePoints(this IEnumerable<Point3> points, int angle) {
foreach (var point in points)
yield return point.RotatePoint(angle);
}
...
}
Now you said you have a 3d primitive matrix with 1s and 0s in it:
int[,,] matrix;
You need to somehow convert the intrinsically defined points in that matrix into a sequence of Point3 instances, rotate those and then convert the resulting sequence back into an int[,,] matrix.
That could be achieved like so (remember about the loss of quality I was talking about earlier):
public static class RotationHelpers {
...
public static IEnumerable<Point3> ToPoints(this int[,,] matrix) {
int lx = matrix.GetLength(0);
int ly = matrix.GetLength(1);
int lz = matrix.GetLength(2);
for (int x = 0; x < lx; x++)
for (int y = 0; y < ly; y++)
for (int z = 0; z < lz; z++) {
bool is1 = matrix[x, y, z] != 0;
if (is1)
yield return new Point3 {
X = x - lx / 2,
Y = y - ly / 2,
Z = z - lz / 2
};
}
}
...
}
That will take all of the cells in the WIDTH x HEIGHT x DEPTH matrix and for every cell which is not equal to 0 it will yield a new Point3 instance with the coordinates of that particular position.
That sequence can then be rotate by an angle using the earlier described RotatePoints method and then the following method could be used to "render" back the resulting sequence of Point3 instances into the array:
public static class RotationHelpers {
...
public static void AssignPoints(this int[,,] matrix, IEnumerable<Point3> points) {
int lx = matrix.GetLength(0);
int ly = matrix.GetLength(1);
int lz = matrix.GetLength(2);
for (int x = 0; x < lx; x++)
for (int y = 0; y < ly; y++)
for (int z = 0; z < lz; z++)
matrix[x, y, z] = 0;
foreach (var point in points) {
// this is when quality is lost, because things like 1.7 and 1.71
// will both become =2
var x = (int)Math.Round(point.X) + lx / 2;
var y = (int)Math.Round(point.Y) + ly / 2;
var z = (int)Math.Round(point.Z) + lz / 2;
// this is where you loose parts of the object because
// it doesn't fit anymore inside the parallelepiped
if ((x >= 0) && (y >= 0) && (z >= 0) &&
(x < lx) && (y < ly) && (z < lz))
matrix[x, y, z] = 1;
}
}
...
}
To wrap it up, you can use all of these methods like so:
int[,,] matrix = ...
int angle = ...
IEnumerable<Point3> points = matrix.ToPoints();
IEnumerable<Point3> rotatedPoints = points.RotatePoints(angle);
matrix.AssignPoints(rotatedPoints);
// now you have the original matrix, rotated by angle

Point of impact: circle collision

I'm doing a school project about robocup where robots are playing football with AI. As everything works fine I am still stuck with something.
The robots are simple spheres drawn from top view. Both player shouldn't be allowed to walk into each other and should get a new updated position on the point of impact.
As the collision handler just checks if they collide or not.. I was hoping if there was a way to detect where the circles collide. So I can update the position of the colliding sphere to the last known non-colliding position so they can't walk trough each other and maybe bounce off.
All points on a circle's circumference are the same distacne, the radius, from the center of the circle. This is true for every circle on the playing field.
Therefore: two circles have collided EXACTLY when the distance between their centres is <= the sum of their respectve radii.
Well, you already marked an answer, but I went and put together a fully functioning piece of code, so maybe you can use it anyway. :) From my comment:
Since they're just circles, just calculate the midpoint between the
circles' centre points. If the circles have different radii, choose
one circle and calculate the point along the line one radius away from
its centre.
This might be a simple implementation. I created some very meager helper classes for it; I would totally encourage extending them, making the structs truly immutable, and all that good jazz, but for now serve okay for demonstration purposes.
So for helper classes:
public struct Point
{
public double X;
public double Y;
public double Distance(Point otherPoint)
{
double deltaX = this.X - otherPoint.X;
double deltaY = this.Y - otherPoint.Y;
return System.Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
}
public override string ToString()
{
return String.Format("({0}, {1})", X, Y);
}
}
public struct Polar
{
public double Radius;
public double Angle;
public double X { get { return Radius * System.Math.Cos(Angle); } }
public double Y { get { return Radius * System.Math.Sin(Angle); } }
public Point ToCartesian()
{
return new Point() { X = X, Y = Y };
}
}
public class Circle
{
public double Radius { get; set; }
public Point Position { get; set; }
}
Our meat-and-potatoes class/method is this:
public class CollisionResult
{
public Circle Circle1 { get; private set; }
public Circle Circle2 { get; private set; }
public Point Circle1SafeLocation { get; private set; }
public Point Circle2SafeLocation { get; private set; }
public Point CollisionLocation { get; private set; }
public CollisionResult(Circle circle1, Circle circle2)
{
this.Circle1 = circle1;
this.Circle2 = circle2;
}
public bool CalculateCollision()
{
double distanceFromCentres = Circle1.Position.Distance(Circle2.Position);
if (distanceFromCentres >= Circle1.Radius + Circle2.Radius)
return false;
double angleBetweenCircles = System.Math.Atan2(Circle2.Position.Y - Circle1.Position.Y, Circle2.Position.X - Circle1.Position.X);
Point midpointBetweenCircles = new Point(){X = (Circle1.Position.X + Circle2.Position.X)/2, Y = (Circle1.Position.Y + Circle2.Position.Y)/2};
Point circle1Offset = (new Polar() { Radius = Circle1.Radius, Angle = System.Math.PI + angleBetweenCircles }).ToCartesian();
Point circle2Offset = (new Polar() { Radius = Circle2.Radius, Angle = angleBetweenCircles }).ToCartesian();
CollisionLocation = midpointBetweenCircles;
Circle1SafeLocation = new Point(){X = midpointBetweenCircles.X + circle1Offset.X, Y = midpointBetweenCircles.Y + circle1Offset.Y };
Circle2SafeLocation = new Point(){X = midpointBetweenCircles.X + circle2Offset.X, Y = midpointBetweenCircles.Y + circle2Offset.Y };
return true;
}
}
Usage might look like:
private void CheckCollision(Circle circle1, Circle circle2)
{
CollisionResult result = new CollisionResult(circle1, circle2);
if (result.CalculateCollision())
{
Console.WriteLine(String.Format("Collision detected at {0}! Safe location for circle 1: {1}, circle 2: {2}", result.CollisionLocation, result.Circle1SafeLocation, result.Circle2SafeLocation));
}
else
{
Console.WriteLine("Did not collide.");
}
}
var circle1 = new Circle() {Radius = 5, Position = new Point(){X = 0, Y = 0} };
var circle2 = new Circle() {Radius = 5, Position = new Point(){X = 10, Y = 0} };
var circle3 = new Circle() {Radius = 3, Position = new Point(){X = 0, Y = 1} };
var circle4 = new Circle() {Radius = 5, Position = new Point(){X = 3, Y = 7} };
CheckCollision(circle1, circle2);
CheckCollision(circle3, circle4);
Outputs:
Did not collide.
Collision detected at (1.5, 4)! Safe location for circle 1: (0.158359213500125, 1.31671842700025), circle 2: (3.73606797749979, 8.47213595499958)
I don't know if it's necessary in your case to deal with the complexity of calculating true intersections of two circles (where they would intersect at two points) and such. Likely something along these lines would be sufficient for you. I definitely encourage healthy unit tests and making the classes proper beyond what I have here. :)
EDIT: Significantly in this case, and this would depend on what you want to do with it for your application, is that when the circles overlap, it simply calculates the midpoint between them then moves each circle away from that midpoint their respective radii. So depending on the speed and size of the circles, or how they are moving, it might produce weird results. For example, if you had a big 10 radius circle sitting still, then you throw in a 1 radius circle only 0.5 distance from the big circle's centre, that big circle is going to shift about 9.75 units! If you don't get into big overlapping conditions, then maybe it's not much of an issue. I think at the very least this will give you some information about the collision and then how you want your circles to react as a result will be up to you.
What you will need to do is to find the point of intersection between the two circles, which could be two points, one point, or none. This is basically done by solving the equations of the two circles together. Here's the math:
http://www.analyzemath.com/CircleEq/circle_intersection.html
Since this is for school I'll leave the coding to you :)

Circle Collision to prevent them from going through eachother [duplicate]

This question already has answers here:
circle-circle collision
(5 answers)
Closed 9 years ago.
Just made a little theory to simplify my problem.. I want to know if it's possible or easier way to do this.
I'm making a game simulation in C# where robots play soccer with AI. But need to prevent them from walking in eachother, find the exact point of impact to update their position so they can't walk into eachother.
Thanks.
This is not a duplicate since I was asking another theory I was working out.
Well, from the answer I already provided from your previous question, is there anything you don't understand or need help with? It does pretty much exactly what you're asking here (so "yes, you can employ polar coordinates like this.")
However, your comment about the "last known position where they didn't collide" would mean you would have to track their positions and maintain their last good state and revert to it. Not sure if that's necessary in this case or if you would rather just calculate a new "best-fit" location.
Well, you already marked an answer, but I went and put together a fully functioning piece of code, so maybe you can use it anyway. :) From my comment:
Since they're just circles, just calculate the midpoint between the
circles' centre points. If the circles have different radii, choose
one circle and calculate the point along the line one radius away from
its centre.
This might be a simple implementation. I created some very meager helper classes for it; I would totally encourage extending them, making the structs truly immutable, and all that good jazz, but for now serve okay for demonstration purposes.
So for helper classes:
public struct Point
{
public double X;
public double Y;
public double Distance(Point otherPoint)
{
double deltaX = this.X - otherPoint.X;
double deltaY = this.Y - otherPoint.Y;
return System.Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
}
public override string ToString()
{
return String.Format("({0}, {1})", X, Y);
}
}
public struct Polar
{
public double Radius;
public double Angle;
public double X { get { return Radius * System.Math.Cos(Angle); } }
public double Y { get { return Radius * System.Math.Sin(Angle); } }
public Point ToCartesian()
{
return new Point() { X = X, Y = Y };
}
}
public class Circle
{
public double Radius { get; set; }
public Point Position { get; set; }
}
Our meat-and-potatoes class/method is this:
public class CollisionResult
{
public Circle Circle1 { get; private set; }
public Circle Circle2 { get; private set; }
public Point Circle1SafeLocation { get; private set; }
public Point Circle2SafeLocation { get; private set; }
public Point CollisionLocation { get; private set; }
public CollisionResult(Circle circle1, Circle circle2)
{
this.Circle1 = circle1;
this.Circle2 = circle2;
}
public bool CalculateCollision()
{
double distanceFromCentres = Circle1.Position.Distance(Circle2.Position);
if (distanceFromCentres >= Circle1.Radius + Circle2.Radius)
return false;
double angleBetweenCircles = System.Math.Atan2(Circle2.Position.Y - Circle1.Position.Y, Circle2.Position.X - Circle1.Position.X);
Point midpointBetweenCircles = new Point(){X = (Circle1.Position.X + Circle2.Position.X)/2, Y = (Circle1.Position.Y + Circle2.Position.Y)/2};
Point circle1Offset = (new Polar() { Radius = Circle1.Radius, Angle = System.Math.PI + angleBetweenCircles }).ToCartesian();
Point circle2Offset = (new Polar() { Radius = Circle2.Radius, Angle = angleBetweenCircles }).ToCartesian();
CollisionLocation = midpointBetweenCircles;
Circle1SafeLocation = new Point(){X = midpointBetweenCircles.X + circle1Offset.X, Y = midpointBetweenCircles.Y + circle1Offset.Y };
Circle2SafeLocation = new Point(){X = midpointBetweenCircles.X + circle2Offset.X, Y = midpointBetweenCircles.Y + circle2Offset.Y };
return true;
}
}
Usage might look like:
private void CheckCollision(Circle circle1, Circle circle2)
{
CollisionResult result = new CollisionResult(circle1, circle2);
if (result.CalculateCollision())
{
Console.WriteLine(String.Format("Collision detected at {0}! Safe location for circle 1: {1}, circle 2: {2}", result.CollisionLocation, result.Circle1SafeLocation, result.Circle2SafeLocation));
}
else
{
Console.WriteLine("Did not collide.");
}
}
var circle1 = new Circle() {Radius = 5, Position = new Point(){X = 0, Y = 0} };
var circle2 = new Circle() {Radius = 5, Position = new Point(){X = 10, Y = 0} };
var circle3 = new Circle() {Radius = 3, Position = new Point(){X = 0, Y = 1} };
var circle4 = new Circle() {Radius = 5, Position = new Point(){X = 3, Y = 7} };
CheckCollision(circle1, circle2);
CheckCollision(circle3, circle4);
Outputs:
Did not collide.
Collision detected at (1.5, 4)! Safe location for circle 1: (0.158359213500125, 1.31671842700025), circle 2: (3.73606797749979, 8.47213595499958)
I don't know if it's necessary in your case to deal with the complexity of calculating true intersections of two circles (where they would intersect at two points) and such. Likely something along these lines would be sufficient for you. I definitely encourage healthy unit tests and making the classes proper beyond what I have here. :)
Significantly in this case, and this would depend on what you want to do with it for your application, is that when the circles overlap, it simply calculates the midpoint between them then moves each circle away from that midpoint their respective radii. So depending on the speed and size of the circles, or how they are moving, it might produce weird results. For example, if you had a big 10 radius circle sitting still, then you throw in a 1 radius circle only 0.5 distance from the big circle's centre, that big circle is going to shift about 9.75 units! If you don't get into big overlapping conditions, then maybe it's not much of an issue. I think at the very least this will give you some information about the collision and then how you want your circles to react as a result will be up to you.
Might be this is helpful for you:
http://www.emanueleferonato.com/2011/06/13/slicing-splitting-and-cutting-objects-with-box2d/
This tutorial consist of four parts and explain the 2D dynamics very well.
The faster way to see if the two circles are colliding is to constantly check their positions. Infact you have to check if the distance between their centers is smaller than the sum of their radius.
Some "pseudo code" could be:
distanceX = Math.Abs(circle1.X - cirlce2.X);
distanceY = Math.Abs(circle1.Y - cirlce2.Y);
distance = Math.Sqrt(distanceX * distanceX - distanceY * distanceY);
if(distance <= circle1.Radius + circle2.Radius){
//they're colliding and the point of collision is:
collisionX = distanceX / 2;
collisionY = distanceY / 2;
if(circle1.X < circle2.X)
collisionX += circle1.X;
else
collisionX += circle2.X;
if(circle1.Y < circle2.Y)
collisionY += circle1.Y;
else
collisionY += circle2.Y;
}
PS: Note that I didn't use Math.Pow() due to its performance.

Intersection of a line and a Sphere?

I have a simple object that allows you to assign three properties (x,y,z) (lets call this object a "point", because that is what it is). I then have a second object with a method that accepts two instances of the first object, and returns the distance between the two "points" in three dimensional space. I also need a method that will accept two "points"
and a double, representing distance traveled (from the first "point" parameter used) that returns a "point" object with its x,y,z coordinates.
I'm ok with everything except the calculation of the point coordinates that are on the original line between the two points supplied, that is at a certain distance from the first point.
"point" object:
public class POR
{
private double PORX;
private double PORY;
private double PORZ;
public double X
{
get { return PORX; }
set { PORX = value; }
}
public double Y
{
get { return PORY; }
set { PORY = value; }
}
public double Z
{
get { return PORZ; }
set { PORZ = value; }
}
public POR(double X, double Y, double Z)
{
PORX = X;
PORY = Y;
PORZ = Z;
}
I'm then using :
public double PorDistance(POR por1, POR por2)
{
return Math.Round(Math.Sqrt( Math.Pow((por1.X - por2.X),2) + Math.Pow((por1.Y - por2.Y),2) + Math.Pow((por1.Z - por2.Z),2)),2);
}
to return the distance between those two points I need something like
public POR IntersectPOR (POR por1, POR por2, double distance)
{
}
where distance is the distance traveled from por1 towards por2.
This can be done with a bit of help from vectors.
Let's say your starting point is called P, and the other point is Q, and the distance is d. You want to find the point on the line PQ at a distance d from P towards Q.
First you need to find the direction of travel. That's done by finding Q - P
v = Point(Q.x - P.x, Q.y - P.y, Q.z - P.z)
Now you need to find the unit vector in that direction, so
scale = sqrt(v.x*v.x + v.y*v.y + v.z*v.z)
unit = Point(v.x/scale, v.y/scale, v.z/scale)
Now you need to find the vector representing the distance traveled:
t = Point(unit.x*d, unit.y*d, unit.z*d)
To find the final position, add your traveled vector to your starting point:
final = Point(P.x + t.x, P.y + t.y, P.z + t.z)
It looks like you want something similar to:
public class Point
{
public double x, y, z;
// ctors, Add(), Subtract() omitted
public Point Normalize()
{
double m = Magnitude;
if (m != 0.0) return ScaleTo(1.0/m);
return new Point();
}
public double Magnitude
{
get { return Math.Sqrt(x * x + y * y + z * z); }
}
public Point ScaleTo(double s)
{
return new Point(x * s, y * s, z * s);
}
}
public Point PointOnLine(Point from, Point to, double dist)
{
return from.Add(to.Subtract(from).Normalize().ScaleTo(dist));
}
No actual code because I think this is more of a conceptual question.
This may not be the most efficient, but when I'm doing this I just apply the ratio between the total distance and the segment to the coordinate deltas.
For example if I have points at 0,0,0 and 1,2,3 the total 3D distance is 3.74, if I want to place a point 1 unit from the first point the ratio is 1/3.74 so the new coordinate would be .2673 of the total distance from the first point toward the second or .267 , .534 , .802

Categories

Resources