I am trying to get more comfortable with the math behind fractal coloring and understanding the coloring algorithms much better. I am the following paper:
http://jussiharkonen.com/files/on_fractal_coloring_techniques%28lo-res%29.pdf
The paper gives specific parameters to each of the functions, however when I use the same, my results are not quite right. I have no idea what could be going on though.
I am using the iteration count coloring algorithm to start and using the following julia set:
c = 0.5 + 0.25i and p = 2
with the coloring algorithm:
The coloring function simply returns the number of
elements in the truncated orbit divided by 20
And the palette function:
I(u) = k(u − u0),
where k = 2.5 and u0 = 0, was used.
And with a palette being white at 0 and 1, and interpolating to black in-between.
and following this algorithm:
Set z0 to correspond to the position of the pixel in the complex plane.
Calculate the truncated orbit by iterating the formula zn = f(zn−1) starting
from z0 until either
• |zn| > M, or
• n = Nmax,
where Nmax is the maximum number of iterations.
Using the coloring and color index functions, map the resulting truncated
orbit to a color index value.
Determine an RGB color of the pixel by using the palette function
Using this my code looks like the following:
float izoom = pow(1.001, zoom );
vec2 z = focusPoint + (uv * 4.0 - 2.0) * 1.0 / izoom;
vec2 c = vec2(0.5f, 0.25f) ;
const float B = 2.0;
float l;
for( int i=0; i<100; i++ )
{
z = vec2( z.x*z.x - z.y*z.y, 2.0*z.x*z.y ) + c;
if( length(z)>10.0) break;
l++;
}
float ind = basicindex(l);
vec4 col = color(ind);
and have the following index and coloring functions:
float basicindex(float val){
return val / 20.0;
}
vec4 color(float index){
float r = 2.5 * index;
float g = r;
float b = g;
vec3 v = 0.5 - 0.5 * sin(3.14/2.0 + 3.14 * vec3(r, g, b));
return vec4(1.0 - v, 1.0) ;
}
The paper provides the following image:
https://imgur.com/YIZMhaa
While my code produces:
https://imgur.com/OrxdMsN
I get the correct results by using k = 1.0 instead of 2.5, however I would prefer to understand why my results are incorrect. When extending this to the smooth coloring algorithms, my results are still incorrect so I would like to figure this out first.
Let me know if this isn't the correct place for this kind of question and I can move it to the math stack exchange. I wasn't sure which place was more appropriate.
Your image is perfectly implemented for Figure 3.3 in the paper. The other image you posted uses a different routine.
Your figure seems to have that bit of perspective code there at top, but remove that and they should be the same.
If your objection is the color extremes you set that with the "0.5 - 0.5 * ..." part of your code. This makes the darkest black originally 0.5 when in the example image you're trying to duplicate the darkest black should be 1 and the lightest white should be 0.
You're making the whiteness equal to the distance from 0.5
If you ignore the fractal all together you are getting a bunch of values that can be normalized between 0 and 1 and you're coloring those in some particular ways. Clearly the image you are duplicating is linear between 0 and 1 so putting black as 0.5 cannot be correct.
o = {
length : 500,
width : 500,
c : [.5, .25], // c = x + iy will be [x, y]
maxIterate : 100,
canvas : null
}
function point(pos, color){
var c = 255 - Math.round((1 + Math.log(color)/Math.log(o.maxIterate)) * 255);
c = c.toString(16);
if (c.length == 1) c = '0'+c;
o.canvas.fillStyle="#"+c+c+c;
o.canvas.fillRect(pos[0], pos[1], 1, 1);
}
function conversion(x, y, R){
var m = R / o.width;
var x1 = m * (2 * x - o.width);
var y2 = m * (o.width - 2 * y);
return [x1, y2];
}
function f(z, c){
return [z[0]*z[0] - z[1] * z[1] + c[0], 2 * z[0] * z[1] + c[1]];
}
function abs(z){
return Math.sqrt(z[0]*z[0] + z[1]*z[1]);
}
function init(){
var R = (1 + Math.sqrt(1+4*abs(o.c))) / 2,
z, x, y, i;
o.canvas = document.getElementById('a').getContext("2d");
for (x = 0; x < o.width; x++){
for (y = 0; y < o.length; y++){
i = 0;
z = conversion(x, y, R);
while (i < o.maxIterate && abs(z) < R){
z = f(z, o.c);
if (abs(z) > R) break;
i++;
}
if (i) point([x, y], i / o.maxIterate);
}
}
}
init();
<canvas id="a" width="500" height="500"></canvas>
via: http://jsfiddle.net/3fnB6/29/
This question is a reverse of these questions:
Find the position nth element of a rectangular tiled spiral?
Coordinate Algorithm - Rotate around the center
Looping in a spiral
Currently I have this code which gets the coordinate of the nth element in a spiral of squares:
private int[] getPos(int n) {
int x = 0, z = 0;
if (--n >= 0) {
int v = (int) Math.floor(Math.sqrt(n + .25) - 0.5);
int spiralBaseIndex = v * (v + 1);
int flipFlop = ((v & 1) << 1) - 1;
int offset = flipFlop * ((v + 1) >> 1);
x += offset; z += offset;
int cornerIndex = spiralBaseIndex + (v + 1);
if (n < cornerIndex) {
x -= flipFlop * (n - spiralBaseIndex + 1);
} else {
x -= flipFlop * (v + 1);
z -= flipFlop * (n - cornerIndex + 1);
}
}
return new int[]{x,z};
}
Now I need a function that maps the other way, any ideas?
Okay. On the assumption that your spiral is, in fact, a square spriral, this is simple enough.
First, we can tell which spiral "level" (or which ring) the position will be on by using this:
//parameter "position" assumed
int level = 0;
int layerSize = 1;
while(position > layerSize * layerSize) {
layerSize += 2;
level++;
}
We know this is the case because each spiral puts squares on either side of the previous spiral (that's the +2) and so the level the position is on is going to be in the area of the largest possible square spiral.
At this point you can use getPos to get the position of (layerSize * layerSize + 1) after that, just walk the spiral shape until your position number is reached.
pls any one help me
i have create the edges in my project.i know how to check touch position is inside the shape
if (fix->TestPoint(locationWorld))
{
CCLOG(#"****touch inside shape***");
}
but i want create hexagon shape and i need to ball create inside hexagon shape and move inside hexagon.
i did ball move inside hexagon shape using below code:
b2BodyDef groundBodyDef;
groundBodyDef.position.Set(0, 0);
b2Body* groundBody = world->CreateBody(&groundBodyDef);
int countVal=[pos count];
// Define the ground box shape.
b2PolygonShape groundBox;
int range=[pos count]-2;
CCLOG(#"countVal=%d,range=%d",countVal,range);
for (int i=0; i<=range; i=i+2)
{
float x1,y1,x2,y2;
x1=[[pos objectAtIndex:i] floatValue];
y1=[[pos objectAtIndex:i+1] floatValue];
if (i==range)
{
x2=[[pos objectAtIndex:0] floatValue];
y2=[[pos objectAtIndex:1] floatValue];
}
else
{
x2=[[pos objectAtIndex:i+2] floatValue];
y2=[[pos objectAtIndex:i+3] floatValue];
}
CCLOG(#"x1=%f,y1=%f,x2=%f,y2=%f",x1,y1,x2,y2);
groundBox.SetAsEdge(b2Vec2(x1/PTM_RATIO,y1/PTM_RATIO),b2Vec2(x2/PTM_RATIO,y2/PTM_RATIO));
groundBody->CreateFixture(&groundBox, 0);
}
but i dont know how to find touch position is inside polygon shape.i use cocos2d with box2d
pls any one help me
Finally i got the answer:
i am checking if the point is inside polygon:
int pnpoly(int npol, float *xp, float *yp, float x, float y)
{
int i, j, c = 0;
for (i = 0, j = npol-1; i < npol; j = i++)
{
if ((((yp[i] <= y) && (y < yp[j])) ||
((yp[j] <= y) && (y < yp[i]))) &&
(x < (xp[j] - xp[i]) * (y - yp[i]) / (yp[j] - yp[i]) + xp[i]))
c = !c;
}
return c;
}
I need a algorithm for detecting if a circle has hit a square, and I saw this post:
Circle-Rectangle collision detection (intersection)
It looks like I should go for ShreevatsaR's answer, but I am a math fool, and I have no idea how to finish the algorithm. Could anyone find the time to make a complete example for me please, I have searched the net for this, and have yet found no working example.
Thank you very much
Soeren
EDIT:
Ok here is my attempt. It is not working, it never detects any collisions.
typedef struct {
double x;
double y;
} point;
typedef struct {
point one;
point two;
} segment;
typedef struct {
point center;
double radius;
} circle;
typedef struct {
point p;
int width;
int height;
point a;
point b;
point c;
point d;
} rectangle;
double slope(point one, point two) {
return (double)(one.y-two.y)/(one.x-two.x);
}
double distance(point p, segment s) {
// Line one is the original line that was specified, and line two is
// the line we're constructing that runs through the specified point,
// at a right angle to line one.
//
// if it's a vertical line return the horizontal distance
if ( s.one.x == s.two.x)
return fabs(s.one.x - p.x);
// if it's a horizontal line return the vertical distance
if ( s.one.y == s.two.y )
return fabs(s.one.y - p.y);
// otherwise, find the slope of the line
double m_one = slope(s.one, s.two);
// the other slope is at a right angle.
double m_two = -1.0 / m_one;
// find the y-intercepts.
double b_one = s.one.y - s.one.x * m_one;
double b_two = p.y - p.x * m_two;
// find the point of intersection
double x = (b_two - b_one) / (m_one - m_two);
double y = m_one * x + b_one;
// find the x and y distances
double x_dist = x - p.x;
double y_dist = y - p.y;
// and return the total distance.
return sqrt(x_dist * x_dist + y_dist * y_dist);
}
bool intersectsCircle(segment s, circle c) {
return distance(c.center, s) <= c.radius;
}
bool pointInRectangle(point p, rectangle r)
{
float right = r.p.x + r.width;
float left = r.p.x - r.width;
float top = r.p.y + r.height;
float bottom = r.p.y - r.height;
return ((left <= p.x && p.x <= right) && (top <= p.y && p.y <= bottom));
}
bool intersect(circle c, rectangle r) {
segment ab;
ab.one = r.a;
ab.two = r.b;
segment bc;
ab.one = r.b;
ab.two = r.c;
segment cd;
ab.one = r.c;
ab.two = r.d;
segment da;
ab.one = r.d;
ab.two = r.a;
return pointInRectangle(c.center, r) ||
intersectsCircle(ab, c) ||
intersectsCircle(bc, c) ||
intersectsCircle(cd, c) ||
intersectsCircle(da, c);
}
The primary part he seems to have left is the InteresectsCircle(line, circle).
#include <math.h>
typedef struct {
double x;
double y;
} point;
typedef struct {
point one;
point two;
} segment;
typedef struct {
point center;
double radius;
} circle;
double slope(point &one, point &two) {
return (double)(one.y-two.y)/(one.x-two.x);
}
double distance(point &p, segment &s) {
// Line one is the original line that was specified, and line two is
// the line we're constructing that runs through the specified point,
// at a right angle to line one.
//
// if it's a vertical line return the horizontal distance
if ( s.one.x == s.two.x)
return fabs(s.one.x - p.x);
// if it's a horizontal line return the vertical distance
if ( s.one.y == s.two.y )
return fabs(s.one.y - p.y);
// otherwise, find the slope of the line
double m_one = slope(s.one, s.two);
// the other slope is at a right angle.
double m_two = -1.0 / m_one;
// find the y-intercepts.
double b_one = s.one.y - s.one.x * m_one;
double b_two = p.y - p.x * m_two;
// find the point of intersection
double x = (b_two - b_one) / (m_one - m_two);
double y = m_one * x + b_one;
// find the x and y distances
double x_dist = x - p.x;
double y_dist = y - p.y;
// and return the total distance.
return sqrt(x_dist * x_dist + y_dist * y_dist);
}
bool IntersectsCircle(segment s, circle c) {
return distance(circle.center, s) <= circle.radius;
}
I have some code in C++ (lightly templated) that should do these intersection tests, but I haven't had time to test them yet. In particular, I have the segment-circle intersection test as well as parallelogram-circle intersection, which is supposed to compute the intersection area and intersection points. Again, this is completely untested as of the writing of this comment, so you will need to test/adapt them to your needs.
How to test if a line segment intersects an axis-aligned rectange in 2D? The segment is defined with its two ends: p1, p2. The rectangle is defined with top-left and bottom-right points.
The original poster wanted to DETECT an intersection between a line segment and a polygon. There was no need to LOCATE the intersection, if there is one. If that's how you meant it, you can do less work than Liang-Barsky or Cohen-Sutherland:
Let the segment endpoints be p1=(x1 y1) and p2=(x2 y2).
Let the rectangle's corners be (xBL yBL) and (xTR yTR).
Then all you have to do is
A. Check if all four corners of the rectangle are on the same side of the line.
The implicit equation for a line through p1 and p2 is:
F(x y) = (y2-y1)*x + (x1-x2)*y + (x2*y1-x1*y2)
If F(x y) = 0, (x y) is ON the line.
If F(x y) > 0, (x y) is "above" the line.
If F(x y) < 0, (x y) is "below" the line.
Substitute all four corners into F(x y). If they're all negative or all positive, there is no intersection. If some are positive and some negative, go to step B.
B. Project the endpoint onto the x axis, and check if the segment's shadow intersects the polygon's shadow. Repeat on the y axis:
If (x1 > xTR and x2 > xTR), no intersection (line is to right of rectangle).
If (x1 < xBL and x2 < xBL), no intersection (line is to left of rectangle).
If (y1 > yTR and y2 > yTR), no intersection (line is above rectangle).
If (y1 < yBL and y2 < yBL), no intersection (line is below rectangle).
else, there is an intersection. Do Cohen-Sutherland or whatever code was mentioned in the other answers to your question.
You can, of course, do B first, then A.
Alejo
Wrote quite simple and working solution:
bool SegmentIntersectRectangle(double a_rectangleMinX,
double a_rectangleMinY,
double a_rectangleMaxX,
double a_rectangleMaxY,
double a_p1x,
double a_p1y,
double a_p2x,
double a_p2y)
{
// Find min and max X for the segment
double minX = a_p1x;
double maxX = a_p2x;
if(a_p1x > a_p2x)
{
minX = a_p2x;
maxX = a_p1x;
}
// Find the intersection of the segment's and rectangle's x-projections
if(maxX > a_rectangleMaxX)
{
maxX = a_rectangleMaxX;
}
if(minX < a_rectangleMinX)
{
minX = a_rectangleMinX;
}
if(minX > maxX) // If their projections do not intersect return false
{
return false;
}
// Find corresponding min and max Y for min and max X we found before
double minY = a_p1y;
double maxY = a_p2y;
double dx = a_p2x - a_p1x;
if(Math::Abs(dx) > 0.0000001)
{
double a = (a_p2y - a_p1y) / dx;
double b = a_p1y - a * a_p1x;
minY = a * minX + b;
maxY = a * maxX + b;
}
if(minY > maxY)
{
double tmp = maxY;
maxY = minY;
minY = tmp;
}
// Find the intersection of the segment's and rectangle's y-projections
if(maxY > a_rectangleMaxY)
{
maxY = a_rectangleMaxY;
}
if(minY < a_rectangleMinY)
{
minY = a_rectangleMinY;
}
if(minY > maxY) // If Y-projections do not intersect return false
{
return false;
}
return true;
}
Since your rectangle is aligned, Liang-Barsky might be a good solution. It is faster than Cohen-Sutherland, if speed is significant here.
Siggraph explanation
Another good description
And of course, Wikipedia
You could also create a rectangle out of the segment and test if the other rectangle collides with it, since it is just a series of comparisons. From pygame source:
def _rect_collide(a, b):
return a.x + a.w > b.x and b.x + b.w > a.x and \
a.y + a.h > b.y and b.y + b.h > a.y
Use the Cohen-Sutherland algorithm.
It's used for clipping but can be slightly tweaked for this task. It divides 2D space up into a tic-tac-toe board with your rectangle as the "center square".
then it checks to see which of the nine regions each of your line's two points are in.
If both points are left, right, top, or bottom, you trivially reject.
If either point is inside, you trivially accept.
In the rare remaining cases you can do the math to intersect with whichever sides of the rectangle are possible to intersect with, based on which regions they're in.
Or just use/copy the code already in the Java method
java.awt.geom.Rectangle2D.intersectsLine(double x1, double y1, double x2, double y2)
Here is the method after being converted to static for convenience:
/**
* Code copied from {#link java.awt.geom.Rectangle2D#intersectsLine(double, double, double, double)}
*/
public class RectangleLineIntersectTest {
private static final int OUT_LEFT = 1;
private static final int OUT_TOP = 2;
private static final int OUT_RIGHT = 4;
private static final int OUT_BOTTOM = 8;
private static int outcode(double pX, double pY, double rectX, double rectY, double rectWidth, double rectHeight) {
int out = 0;
if (rectWidth <= 0) {
out |= OUT_LEFT | OUT_RIGHT;
} else if (pX < rectX) {
out |= OUT_LEFT;
} else if (pX > rectX + rectWidth) {
out |= OUT_RIGHT;
}
if (rectHeight <= 0) {
out |= OUT_TOP | OUT_BOTTOM;
} else if (pY < rectY) {
out |= OUT_TOP;
} else if (pY > rectY + rectHeight) {
out |= OUT_BOTTOM;
}
return out;
}
public static boolean intersectsLine(double lineX1, double lineY1, double lineX2, double lineY2, double rectX, double rectY, double rectWidth, double rectHeight) {
int out1, out2;
if ((out2 = outcode(lineX2, lineY2, rectX, rectY, rectWidth, rectHeight)) == 0) {
return true;
}
while ((out1 = outcode(lineX1, lineY1, rectX, rectY, rectWidth, rectHeight)) != 0) {
if ((out1 & out2) != 0) {
return false;
}
if ((out1 & (OUT_LEFT | OUT_RIGHT)) != 0) {
double x = rectX;
if ((out1 & OUT_RIGHT) != 0) {
x += rectWidth;
}
lineY1 = lineY1 + (x - lineX1) * (lineY2 - lineY1) / (lineX2 - lineX1);
lineX1 = x;
} else {
double y = rectY;
if ((out1 & OUT_BOTTOM) != 0) {
y += rectHeight;
}
lineX1 = lineX1 + (y - lineY1) * (lineX2 - lineX1) / (lineY2 - lineY1);
lineY1 = y;
}
}
return true;
}
}
A quick Google search popped up a page with C++ code for testing the intersection.
Basically it tests the intersection between the line, and every border or the rectangle.
Rectangle and line intersection code
Here's a javascript version of #metamal's answer
var isRectangleIntersectedByLine = function (
a_rectangleMinX,
a_rectangleMinY,
a_rectangleMaxX,
a_rectangleMaxY,
a_p1x,
a_p1y,
a_p2x,
a_p2y) {
// Find min and max X for the segment
var minX = a_p1x
var maxX = a_p2x
if (a_p1x > a_p2x) {
minX = a_p2x
maxX = a_p1x
}
// Find the intersection of the segment's and rectangle's x-projections
if (maxX > a_rectangleMaxX)
maxX = a_rectangleMaxX
if (minX < a_rectangleMinX)
minX = a_rectangleMinX
// If their projections do not intersect return false
if (minX > maxX)
return false
// Find corresponding min and max Y for min and max X we found before
var minY = a_p1y
var maxY = a_p2y
var dx = a_p2x - a_p1x
if (Math.abs(dx) > 0.0000001) {
var a = (a_p2y - a_p1y) / dx
var b = a_p1y - a * a_p1x
minY = a * minX + b
maxY = a * maxX + b
}
if (minY > maxY) {
var tmp = maxY
maxY = minY
minY = tmp
}
// Find the intersection of the segment's and rectangle's y-projections
if(maxY > a_rectangleMaxY)
maxY = a_rectangleMaxY
if (minY < a_rectangleMinY)
minY = a_rectangleMinY
// If Y-projections do not intersect return false
if(minY > maxY)
return false
return true
}
I did a little napkin solution..
Next find m and c and hence the equation y = mx + c
y = (Point2.Y - Point1.Y) / (Point2.X - Point1.X)
Substitute P1 co-ordinates to now find c
Now for a rectangle vertex, put the X value in the line equation, get the Y value and see if the Y value lies in the rectangle bounds shown below
(you can find the constant values X1, X2, Y1, Y2 for the rectangle such that)
X1 <= x <= X2 &
Y1 <= y <= Y2
If the Y value satisfies the above condition and lies between (Point1.Y, Point2.Y) - we have an intersection.
Try every vertex if this one fails to make the cut.
I was looking at a similar problem and here's what I came up with. I was first comparing the edges and realized something. If the midpoint of an edge that fell within the opposite axis of the first box is within half the length of that edge of the outer points on the first in the same axis, then there is an intersection of that side somewhere.
But that was thinking 1 dimensionally and required looking at each side of the second box to figure out.
It suddenly occurred to me that if you find the 'midpoint' of the second box and compare the coordinates of the midpoint to see if they fall within 1/2 length of a side (of the second box) of the outer dimensions of the first, then there is an intersection somewhere.
i.e. box 1 is bounded by x1,y1 to x2,y2
box 2 is bounded by a1,b1 to a2,b2
the width and height of box 2 is:
w2 = a2 - a1 (half of that is w2/2)
h2 = b2 - b1 (half of that is h2/2)
the midpoints of box 2 are:
am = a1 + w2/2
bm = b1 + h2/2
So now you just check if
(x1 - w2/2) < am < (x2 + w2/2) and (y1 - h2/2) < bm < (y2 + h2/2)
then the two overlap somewhere.
If you want to check also for edges intersecting to count as 'overlap' then
change the < to <=
Of course you could just as easily compare the other way around (checking midpoints of box1 to be within 1/2 length of the outer dimenions of box 2)
And even more simplification - shift the midpoint by your half lengths and it's identical to the origin point of that box. Which means you can now check just that point for falling within your bounding range and by shifting the plain up and to the left, the lower corner is now the lower corner of the first box. Much less math:
(x1 - w2) < a1 < x2
&&
(y1 - h2) < b1 < y2
[overlap exists]
or non-substituted:
( (x1-(a2-a1)) < a1 < x2 ) && ( (y1-(b2-b1)) < b1 < y2 ) [overlap exists]
( (x1-(a2-a1)) <= a1 <= x2 ) && ( (y1-(b2-b1)) <= b1 <= y2 ) [overlap or intersect exists]
coding example in PHP (I'm using an object model that has methods for things like getLeft(), getRight(), getTop(), getBottom() to get the outer coordinates of a polygon and also has a getWidth() and getHeight() - depending on what parameters were fed it, it will calculate and cache the unknowns - i.e. I can create a polygon with x1,y1 and ... w,h or x2,y2 and it can calculate the others)
I use 'n' to designate the 'new' item being checked for overlap ($nItem is an instance of my polygon object) - the items to be tested again [this is a bin/sort knapsack program] are in an array consisting of more instances of the (same) polygon object.
public function checkForOverlaps(BinPack_Polygon $nItem) {
// grab some local variables for the stuff re-used over and over in loop
$nX = $nItem->getLeft();
$nY = $nItem->getTop();
$nW = $nItem->getWidth();
$nH = $nItem->getHeight();
// loop through the stored polygons checking for overlaps
foreach($this->packed as $_i => $pI) {
if(((($pI->getLeft() - $nW) < $nX) && ($nX < $pI->getRight())) &&
((($pI->getTop() - $nH) < $nY) && ($nY < $pI->getBottom()))) {
return false;
}
}
return true;
}
Some sample code for my solution (in php):
// returns 'true' on overlap checking against an array of similar objects in $this->packed
public function checkForOverlaps(BinPack_Polygon $nItem) {
$nX = $nItem->getLeft();
$nY = $nItem->getTop();
$nW = $nItem->getWidth();
$nH = $nItem->getHeight();
// loop through the stored polygons checking for overlaps
foreach($this->packed as $_i => $pI) {
if(((($pI->getLeft() - $nW) < $nX) && ($nX < $pI->getRight())) && ((($pI->getTop() - $nH) < $nY) && ($nY < $pI->getBottom()))) {
return true;
}
}
return false;
}