I have two points in my coordinate system (x,y) that I want to know the angle of their line and x-axis.
I use swift for solving this but I can't get the angle.
I need this angle in radians to use it in the following equation:
(x0 + r cos theta, y0 + r sin theta)
r : radius of circle
If you have two points, (x0, y0) and (x1, y1), then the angle of the line joining them (relative to the X axis) is given by:
theta = atan2((y1 - y0), (x1 - x0))
The angle between a line, for reference, let's call this A, defined by two points p1=(x1,y1),p2=(x2, y2) and the x-axis is related to finding the slope/ gradient of the line, A.
# To solve a problem you sometimes have to simplify it and then work up to the full solution"
Let's start by obtaining the gradient of the line A.
The gradient of line A:
slope = (y2 - y1)/(x2 - x1)
for a straight line, that makes an angle theta with the x-axis
tan(theta) = slope = (change in y) / (change in x)
Therefore, theta = tan_inverse (slope)
theta = atan(slope)
Please can you tell me how I can draw 4th order bezier curve in Geogebra?
I have these polynomial cubics
B0(t) = (1 - t)3,
B1(t) = 3t(1 - t)2,
B2(t) = 3t2(1 - t),
B3(t) = t3
but with these I can draw only simple Bezier curve and I need 4th order bezier curve with 5 control points.
If you have endpoints A, E and control points B, C, D, you can create the 4th degree Bézier curve using this GeoGebra command:
Curve(t⁴ A + 4t³ (1 - t) B + 6t² (1 - t)² C + 4t (1 - t)³ D + (1 - t)⁴ E, t, 0, 1)
You can get the polynomials by multiplying the binomial coefficients with corresponding powers of t and (1-t), see explicit definition of Bézier curve on Wikipedia for details.
I am trying to find a way to create a random closed smooth path (CGPath or UIBezierPath). I have read about the De Casteljau's algorithm and tons other articles about Bezier paths but it does not seem to fit to what I try to achieve.
I thought about creating a circle CGPath. Then I would multiplicate the path by a function that would distort the positions of the points say, sine or cosine. However I don't know if this is the right direction to go since the path would not have a random shape.
CGMutablePathRef circle = CGPathCreateMutable();
CGPathAddArc(circle, nil, 0.0f, 0.0f, 100.0f, 2 * M_PI, 0.0f, true);
...
CGPathRelease(circle);
It would be great if anyone could point me in a right direction how to start implementing it. Example of a path I am trying to generate:
What you've drawn looks like a distorted circle.
Assuming that's what you are after, here is what I would do:
Write code that steps an angle from 0 to 2pi by a fixed number of steps. (Try 8) Have the angle vary by some small random amount less than ± pi/steps.
Pick a base radius that is somewhat less than 1/2 the length of a side of the enclosing square, so there is room to make your points go inside or outside the base radius without going outside your bounding square. Try 3/8 of your bounding box length.
For each slightly randomized angle value along the circle, calculate a radius value that is base radius ± a random value from 0 to base radius/2.
Use sine and cosine to convert your angle and radius values into x and y coordinates for a point.
Add each point to an array. If you use those points to create a closed path, it would give you an 8-sided irregular non-selfintersecting polygon that is a distorted circle.
Now use those points as the control points for a Catmull-Rom spline to turn it into a smooth curve.
EDIT: I created a project on github called RandomBlobs that does what I describe above, as well as another approach:
Break the square area into a 3x3 grid of smaller squares. Ignore the center square.
Walk around the 8 remaining squares clockwise. For each square, pick a random x/y coorindate inside the square (but prevent it from getting too close to the edges.)
Create closed UIBezierPath connecting the 8 points in order.
Use Catmull-Rom smoothing to turn the irregular octagon into a smooth curve.
Yet a third approach would probably be even simpler:
Use a circular layout like in the first approach outlined above. Pick random control points. But then instead of using Catmull-Rom splines, bisect the angle between each pair of endpoints on the distorted circle and add a control point for a quadratic Bezier curve, also with a randomized radius value. So as you walk around the circle, you'd have alternating endpoints and control points. You might need to add some constraints to the bezier control points so you don't have "kinks" in your curved shape (In order to avoid kinks, the control points for neighboring Bezier curves need to follow a line through the shared end-point of the two curves.)
Here are a couple of sample images from the RandomBlobs project. The images I've uploaded are scaled down. The program optionally shows the control points it uses to generate each image, but you can't really see the control points in the scaled-down image.
First, a circle-based blob (using the first method that Josh Caswell and I suggested):
In that picture, the starting circle shape is shown in light gray:
And second, a blob based on the second square-based technique I described:
And in that picture, the grid of squares is shown for reference. The shape is based on a random point in each of the points in the grid (excluding the center square).
I've try to build your path, but it's not perfect... Anyhow, I'll share my test ;-D Hop this can help.
//
// DrawView.h
// test
//
// Created by Armand DOHM on 03/03/2014.
//
//
#import <UIKit/UIKit.h>
#interface DrawView : UIView
#end
//
// DrawView.m
// test
//
// Created by Armand DOHM on 03/03/2014.
//
//
#import "DrawView.h"
#import <math.h>
#implementation DrawView
- (void)drawRect:(CGRect)rect
{
float r; //radius
float rmax = MIN(rect.size.height,rect.size.width) * .5; //max radius
float rmin = rmax * .1; //min radius
NSMutableArray *points = [[NSMutableArray alloc] init];
/*cut a circle into x pies. for each of this pie take a point at a random radius
link all of this point with quadcurve*/
for (double a=0;a < 2 * M_PI;a += M_PI / 10) {
r = rmin + ((arc4random_uniform((int)(rmax - rmin) * 100)) / 100.0f);
CGPoint p = CGPointMake((rect.size.width / 2) + (r * cos (a)) , (rect.size.height / 2) + (r * sin (a)));
[points addObject:[NSValue valueWithCGPoint:p]];
}
UIBezierPath *myPath=[[UIBezierPath alloc]init];
myPath.lineWidth=2;
[myPath strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
r = rmin + ((arc4random_uniform((int)(rmax - rmin) * 100)) / 100.0f);
[myPath moveToPoint:CGPointMake((rect.size.width / 2) + (r * cos (0)) , (rect.size.height / 2) + (r * sin (0)))];
for (int i = 0; i < points.count; i+=2) {
NSValue *value = [points objectAtIndex:i];
CGPoint p1 = [value CGPointValue];
value = [points objectAtIndex:(i+1)];
CGPoint p2 = [value CGPointValue];
[myPath addQuadCurveToPoint:p2 controlPoint:p1];
}
[myPath closePath];
[myPath stroke];
}
#end
I know how to draw simple lines using Core Graphics. I now need to draw a Dimension line for measurements. See the image below for an example of what I need to draw (in red). The top line would be easy, but drawing the perpendicular on a diagonal line will require some math that I'm having a difficult time figuring out right now.
Each main line will have (x,y) as a starting point and (x1,y1) as an ending point. I then need to draw the perpendicular lines that intersect at each of the points (x,y) and (x1,y1).
What is the math required to calculate the points for these perpendicular lines?
The following code computes a vector of length 1 that is perpendicular to
the line from p = (x, y) to p1 = (x1, y1):
CGPoint p = CGPointMake(x, y);
CGPoint p1 = CGPointMake(x1, y1);
// Vector from p to p1;
CGPoint diff = CGPointMake(p1.x - p.x, p1.y - p.y);
// Distance from p to p1:
CGFloat length = hypotf(diff.x, diff.y);
// Normalize difference vector to length 1:
diff.x /= length;
diff.y /= length;
// Compute perpendicular vector:
CGPoint perp = CGPointMake(-diff.y, diff.x);
Now you add and subtract a multiple of that perpendicular vector to the first point
to get the endpoints of the first marker line at p:
CGFloat markLength = 3.0; // Whatever you need ...
CGPoint a = CGPointMake(p.x + perp.x * markLength/2, p.y + perp.y * markLength/2);
CGPoint b = CGPointMake(p.x - perp.x * markLength/2, p.y - perp.y * markLength/2);
For the second marker line, just repeat the last calculation with p1 instead of p.
Given two rectangles with x, y, width, height in pixels and a rotation value in degrees -- how do I calculate the closest distance of their outlines toward each other?
Background: In a game written in Lua I'm randomly generating maps, but want to ensure certain rectangles aren't too close to each other -- this is needed because maps become unsolvable if the rectangles get into certain close-distance position, as a ball needs to pass between them. Speed isn't a huge issue as I don't have many rectangles and the map is just generated once per level. Previous links I found on StackOverflow are this and this
Many thanks in advance!
Not in Lua, a Python code based on M Katz's suggestion:
def rect_distance((x1, y1, x1b, y1b), (x2, y2, x2b, y2b)):
left = x2b < x1
right = x1b < x2
bottom = y2b < y1
top = y1b < y2
if top and left:
return dist((x1, y1b), (x2b, y2))
elif left and bottom:
return dist((x1, y1), (x2b, y2b))
elif bottom and right:
return dist((x1b, y1), (x2, y2b))
elif right and top:
return dist((x1b, y1b), (x2, y2))
elif left:
return x1 - x2b
elif right:
return x2 - x1b
elif bottom:
return y1 - y2b
elif top:
return y2 - y1b
else: # rectangles intersect
return 0.
where
dist is the euclidean distance between points
rect. 1 is formed by points (x1, y1) and (x1b, y1b)
rect. 2 is formed by points (x2, y2) and (x2b, y2b)
Edit: As OK points out, this solution assumes all the rectangles are upright. To make it work for rotated rectangles as the OP asks you'd also have to compute the distance from the corners of each rectangle to the closest side of the other rectangle. But you can avoid doing that computation in most cases if the point is above or below both end points of the line segment, and to the left or right of both line segments (in telephone positions 1, 3, 7, or 9 with respect to the line segment).
Agnius's answer relies on a DistanceBetweenLineSegments() function. Here is a case analysis that does not:
(1) Check if the rects intersect. If so, the distance between them is 0.
(2) If not, think of r2 as the center of a telephone key pad, #5.
(3) r1 may be fully in one of the extreme quadrants (#1, #3, #7, or #9). If so
the distance is the distance from one rect corner to another (e.g., if r1 is
in quadrant #1, the distance is the distance from the lower-right corner of
r1 to the upper-left corner of r2).
(4) Otherwise r1 is to the left, right, above, or below r2 and the distance is
the distance between the relevant sides (e.g., if r1 is above, the distance
is the distance between r1's low y and r2's high y).
Actually there is a fast mathematical solution.
Length(Max((0, 0), Abs(Center - otherCenter) - (Extent + otherExtent)))
Where Center = ((Maximum - Minimum) / 2) + Minimum and Extent = (Maximum - Minimum) / 2.
Basically the code above zero's axis which are overlapping and therefore the distance is always correct.
It's preferable to keep the rectangle in this format as it's preferable in many situations ( a.e. rotations are much easier ).
Pseudo-code:
distance_between_rectangles = some_scary_big_number;
For each edge1 in Rectangle1:
For each edge2 in Rectangle2:
distance = calculate shortest distance between edge1 and edge2
if (distance < distance_between_rectangles)
distance_between_rectangles = distance
There are many algorithms to solve this and Agnius algorithm works fine. However I prefer the below since it seems more intuitive (you can do it on a piece of paper) and they don't rely on finding the smallest distance between lines but rather the distance between a point and a line.
The hard part is implementing the mathematical functions to find the distance between a line and a point, and to find if a point is facing a line. You can solve all this with simple trigonometry though. I have below the methodologies to do this.
For polygons (triangles, rectangles, hexagons, etc.) in arbitrary angles
If polygons overlap, return 0
Draw a line between the centres of the two polygons.
Choose the intersecting edge from each polygon. (Here we reduce the problem)
Find the smallest distance from these two edges. (You could just loop through each 4 points and look for the smallest distance to the edge of the other shape).
These algorithms work as long as any two edges of the shape don't create angles more than 180 degrees. The reason is that if something is above 180 degrees then it means that the some corners are inflated inside, like in a star.
Smallest distance between an edge and a point
If point is not facing the face, then return the smallest of the two distances between the point and the edge cornerns.
Draw a triangle from the three points (edge's points plus the solo point).
We can easily get the distances between the three drawn lines with Pythagorean Theorem.
Get the area of the triangle with Heron's formula.
Calculate the height now with Area = 12⋅base⋅height with base being the edge's length.
Check to see if a point faces an edge
As before you make a triangle from an edge and a point. Now using the Cosine law you can find all the angles with just knowing the edge distances. As long as each angle from the edge to the point is below 90 degrees, the point is facing the edge.
I have an implementation in Python for all this here if you are interested.
This question depends on what kind of distance. Do you want, distance of centers, distance of edges or distance of closest corners?
I assume you mean the last one. If the X and Y values indicate the center of the rectangle then you can find each the corners by applying this trick
//Pseudo code
Vector2 BottomLeftCorner = new Vector2(width / 2, heigth / 2);
BottomLeftCorner = BottomLeftCorner * Matrix.CreateRotation(MathHelper.ToRadians(degrees));
//If LUA has no built in Vector/Matrix calculus search for "rotate Vector" on the web.
//this helps: http://www.kirupa.com/forum/archive/index.php/t-12181.html
BottomLeftCorner += new Vector2(X, Y); //add the origin so that we have to world position.
Do this for all corners of all rectangles, then just loop over all corners and calculate the distance (just abs(v1 - v2)).
I hope this helps you
I just wrote the code for that in n-dimensions. I couldn't find a general solution easily.
// considering a rectangle object that contains two points (min and max)
double distance(const rectangle& a, const rectangle& b) const {
// whatever type you are using for points
point_type closest_point;
for (size_t i = 0; i < b.dimensions(); ++i) {
closest_point[i] = b.min[i] > a.min[i] ? a.max[i] : a.min[i];
}
// use usual euclidian distance here
return distance(a, closest_point);
}
For calculating the distance between a rectangle and a point you can:
double distance(const rectangle& a, const point_type& p) const {
double dist = 0.0;
for (size_t i = 0; i < dimensions(); ++i) {
double di = std::max(std::max(a.min[i] - p[i], p[i] - a.max[i]), 0.0);
dist += di * di;
}
return sqrt(dist);
}
If you want to rotate one of the rectangles, you need to rotate the coordinate system.
If you want to rotate both rectangles, you can rotate the coordinate system for rectangle a. Then we have to change this line:
closest_point[i] = b.min[i] > a.min[i] ? a.max[i] : a.min[i];
because this considers there is only one candidate as the closest vertex in b. You have to change it to check the distance to all vertexes in b. It's always one of the vertexes.
See: https://i.stack.imgur.com/EKJmr.png
My approach to solving the problem:
Combine the two rectangles into one large rectangle
Subtract from the large rectangle the first rectangle and the second
rectangle
What is left after the subtraction is a rectangle between the two
rectangles, the diagonal of this rectangle is the distance between
the two rectangles.
Here is an example in C#
public static double GetRectDistance(this System.Drawing.Rectangle rect1, System.Drawing.Rectangle rect2)
{
if (rect1.IntersectsWith(rect2))
{
return 0;
}
var rectUnion = System.Drawing.Rectangle.Union(rect1, rect2);
rectUnion.Width -= rect1.Width + rect2.Width;
rectUnion.Width = Math.Max(0, rectUnion.Width);
rectUnion.Height -= rect1.Height + rect2.Height;
rectUnion.Height = Math.Max(0, rectUnion.Height);
return rectUnion.Diagonal();
}
public static double Diagonal(this System.Drawing.Rectangle rect)
{
return Math.Sqrt(rect.Height * rect.Height + rect.Width * rect.Width);
}
Please check this for Java, it has the constraint all rectangles are parallel, it returns 0 for all intersecting rectangles:
public static double findClosest(Rectangle rec1, Rectangle rec2) {
double x1, x2, y1, y2;
double w, h;
if (rec1.x > rec2.x) {
x1 = rec2.x; w = rec2.width; x2 = rec1.x;
} else {
x1 = rec1.x; w = rec1.width; x2 = rec2.x;
}
if (rec1.y > rec2.y) {
y1 = rec2.y; h = rec2.height; y2 = rec1.y;
} else {
y1 = rec1.y; h = rec1.height; y2 = rec2.y;
}
double a = Math.max(0, x2 - x1 - w);
double b = Math.max(0, y2 - y1 - h);
return Math.sqrt(a*a+b*b);
}
Another solution, which calculates a number of points on the rectangle and choses the pair with the smallest distance.
Pros: works for all polygons.
Cons: a little bit less accurate and slower.
import numpy as np
import math
POINTS_PER_LINE = 100
# get points on polygon outer lines
# format of polygons: ((x1, y1), (x2, y2), ...)
def get_points_on_polygon(poly, points_per_line=POINTS_PER_LINE):
all_res = []
for i in range(len(poly)):
a = poly[i]
if i == 0:
b = poly[-1]
else:
b = poly[i-1]
res = list(np.linspace(a, b, points_per_line))
all_res += res
return all_res
# compute minimum distance between two polygons
# format of polygons: ((x1, y1), (x2, y2), ...)
def min_poly_distance(poly1, poly2, points_per_line=POINTS_PER_LINE):
poly1_points = get_points_on_polygon(poly1, points_per_line=points_per_line)
poly2_points = get_points_on_polygon(poly2, points_per_line=points_per_line)
distance = min([math.sqrt((a[0] - b[0])**2 + (a[1] - b[1])**2) for a in poly1_points for b in poly2_points])
# slower
# distance = min([np.linalg.norm(a - b) for a in poly1_points for b in poly2_points])
return distance