Related
Can anyone suggest how to handle the following case for the SPOJ-Tourist problem( http://www.spoj.com/problems/TOURIST/ )?
The case is:
5 5
.****
*###*
*.*.*
.####
.*.*.
My implementation is similar to this sample code( mentioned in How to solve this by recursion? )
const int N 100+5
vector<string> board;
int dp[N][N][N]; // initialize with -1
int calc(int x1, int y1, int x2) {
int n=board.size(), m=board[0].size();
int y2=x1+y1-x2;
if(x1>=n || x2>=n || y1>=m || y2>=m) return 0; // out of range
if(board[x1][y1]=='#' || board[x2][y2]=='#') return 0; // path blocked so its an invalid move
if(dp[x1][y1][x2]!=-1) return dp[x1][y1][x2]; // avoid recalculation
int res=0;
if(board[x1][y1]=='*') res++;
if(board[x2][y2]=='*') res++;
if(board[x1][y1]=='*' && x1==x2 && y1==y2) res=1; // both tourist on same spot
int r=calc(x1+1, y1, x2); // first tourist down second tourist right
r=max(r, calc(x1+1, y1, x2+1)); // first tourist down second tourist down
r=max(r, calc(x1, y1+1, x2)); // first tourist right second tourist right
r=max(r, calc(x1, y1+1, x2+1)); // first tourist right second tourist down
res+=r;
dp[x1][y1][x2]=res; // memoize
return res;
}
But I guess this won't work for the above case.
The ans should be 4 but it is giving 8 as output.
Your call this:
calc(x1+1, y1, x2+1)
seems to be culprit. Because both your +1 to x1 & x2 will cancel out & y2 will be same as previous y2. Your condition
if(dp[x1][y1][x2]!=-1) return dp[x1][y1][x2];
prevents infinite loop but results in counting value of each position again.
One simple solution that came is: instead of sending (x1+1, y1, x2+1) etc, send (x1,y1,x2) and one control information say 0(1R-2R),1(1R-2D),2(1D-2R),3(1D-2D). And then based on control information, calculate new pair of (x1, y1) & (x2,y2)
I would like to know if there is any possibility of representing the UML2 Boundary/Control/Entity symbols of a Sequence Diagram in UMLet ? (http://www.uml.org.cn/oobject/images/seq02.gif)
Do I have to write their java code myself or does it already exist somewhere ?
This is the snippet I used to create a boundary symbol in UMLet. You can alter it as needed.
int h = height - textHeight() * textlines.size();
int radius = h/2;
drawCircle(width-radius, radius, radius);
drawLine(0, 10, 0, h-10);
drawLine(0, radius, width-h, radius);
int y = textHeight()+5;
for(String textline : textlines) {
printCenter(textline, height-3);
}
Preview:
I am not sure whether you are referring to Sequence, or Sequence all-in-one.
While those new lifelines are not supported, you can easily add a custom element to the former. There is a nice and easy tutorial how to add a new element here http://www.umlet.com/ce/ce.htm
If you want to add it to the all-in-one, you would need to dive into the internals, since it would require also changes in the text parser.
So I sort of made some models based on Noah's own. It's far from being a professional thing, and is pretty dirty code, but it does the trick for some time, I guess. So if anyone ever gets the same problem as me before these symbols are better implemented in UMLet :
Entity :
int h = height - textHeight() * textlines.size();
int radius = h*2/5;
int w = radius*2 ;
double x = (width - w)/2 + radius ;
double y = h/10 + radius;
double x2 = x + radius/4 * Math.sqrt(3);
double y2 = y - radius/4 ;
drawCircle((int)x, (int) y, radius);
drawLine((int)x-radius , (int)y + radius , (int) x+ radius, (int) y+radius);
drawLine((int)x - radius , (int) y - 2*radius , (int) x + radius, (int) y - 2*radius);
for(String textline : textlines) {
printCenter(textline, h);
}
Control :
int h = height - textHeight() * textlines.size();
int radius = h*2/5;
int w = radius*2 ;
double x1 = (width - w)/2 + radius ;
double y1 = h/10;
double x2 = x1 + radius/4 * Math.sqrt(3);
double y2 = y1 - radius/4 ;
double x3 = x1 + radius/4 * Math.sqrt(3);
double y3 = y1 + radius/4;
drawCircle((int)x1, (int) y1+radius, radius);
drawLine((int)x1, (int) y1 , (int)x2, (int)y2);
drawLine((int)x1, (int) y1 , (int)x3, (int)y3);
int y = textHeight()+5;
for(String textline : textlines) {
printCenter(textline, h);
}
I have a problem with equality and adding objects to dictionary
class DoublePoint
{
public double X;
public double Y;
public double Z;
public DoublePoint(double x, double y, double z)
{
this.X = x; this.Y = y; this.Z = z;
}
public override bool Equals(object obj)
{
try
{
DoublePoint dPoint = obj as DoublePoint;
return this.X.IsEqualTo(dPoint.X) && this.Y.IsEqualTo(dPoint.Y) && this.Z.IsEqualTo(dPoint.Z);
}
catch
{
throw;
}
}
public override int GetHashCode()
{
return this.X.GetCode() ^ this.Y.GetCode() ^ this.Z.GetCode();
}
}
static class extensions
{
static double Tolerance = 0.001;
public static bool IsEqualTo(this double d1, double d2)
{
return (d1 - d2) <= Tolerance;
}
public static int GetCode(this double d1)
{
byte[] data = BitConverter.GetBytes(d1);
int x = BitConverter.ToInt32(data, 0);
int y = BitConverter.ToInt32(data, 4);
return x ^ y;
}
}
and here is my test:
DoublePoint d1 = new DoublePoint(1.200, 2.3, 3.4);
DoublePoint d2 = new DoublePoint(1.2001, 2.3, 3.4);
DoublePoint d3 = new DoublePoint(1.200, 2.3, 3.4);
bool isEqual = d1.Equals(d2); // true here
Dictionary<DoublePoint, int> dict = new Dictionary<DoublePoint, int>();
dict.Add(d1, 1);
dict.Add(d2, 2); // successful, d2 is also added but d2 is equal to d1
dict.Add(d3, 3); // Error! since we have d1 already in dictionary
With this,
when I add doublpoint objects which are same(with some tolerance), I am able to add them in dictionary. How to restrict such objects.
Is the right way to compare double data types with some tolerance.
Please advice.
Thank you
There is a problem with defining "equal" as "close enough". It is no doubt useful for computations, but such "equal" violates the transitivity rule: for Equals if a.Equals(b) && b.Equals(c), then a.Equals(c) must hold true (which is obviously not the property of your code).
So, IsEqualTo is unfortunately not suitable for redefining Equals.
What are the possible ways to solve the problem? Equals has to split into the disjoint groups of "equivalent" values. I usually do the following: define a rule to get the "canonical" value from a group, so two values are "equal" iff their canonical group representatives are equal.
Simple example: for just a double value d let's define the canonical value to be Math.Floor(d). So this way you have 1.0 equals 1.1, 0.9 equals to 0.0 but doesn't equal to 1.0. This way is not the ideal one (after all, 0.9 being not equal to 1.0 but equal to 0.0 seems to be wrong), but at least the transitivity rule is held.
Specifically for your case it could be this way:
class DoublePoint
{
public double X;
public double Y;
public double Z;
const double epsilon;
void GetCanonicalValues(out double x, out double y, out double z)
{
x = Math.Floor(X / epsilon) * epsilon;
y = Math.Floor(Y / epsilon) * epsilon;
z = Math.Floor(Z / epsilon) * epsilon;
}
public override bool Equals(object obj)
{
DoublePoint that = obj as DoublePoint;
if (that == null)
return false;
double x1, y1, z1, x2, y2, z2;
this.GetCanonicalValues(out x1, out x2, out z2);
that.GetCanonicalValues(out x1, out x2, out z2);
return (x1 == x2) && (y1 == y2) && (z1 == z2); // here we can compare
}
...
Another problem with your code is that your GetHashCode is not aligned with Equals: if a.Equals(b) then a.GetHashCode() must equal b.GetHashCode().
You can solve this as well by using the canonical values:
public override int GetHashCode()
{
double x, y, z;
GetCanonicalValues(out x, out y, out z);
return x.GetHashCode() ^ y.GetHashCode() ^ z.GetCode();
}
}
Beware that the behaviour of Equals may be unacceptable for your needs -- then you'll need to ensure the transitivity some other way.
I'm making a game where a grid that is x by y square views big. What I'd like to do is be able to create the grid programmatically.
I had something along these lines in mind.
int across = x
int down = y
CGRect dimentions = foo, bar //etc
int distanceBetween = z
///some crazy loop to make it
If possible I'd also like to keep a reference to each, ideally by assigning tags so I can manipulate them later..
Cheers
S
I think this should do the trick
int across = x
int down = y
CGSize dimensions; // make a cgsize here with the correct values
int distanceBetween = z;
NSMutableArray *views = [[NSMutableArray alloc] init];
for (int x = 0; x < across; x++) {
NSMutableArray *downViews = [[NSMutableArray alloc] init];
for (int y = 0; y < down; y++) {
UIView *view; //create view using the dimensions and padding
//any additional setup to the views
[downViews addObject:view];
}
[views addObject:downViews];
[downViews release];
}
Basically it's just a matter of setting the grid sizes and then calculating the x and y positions from there.
It should calculate how many columns across based on the frame size. So that if the frame widens it will show more columns. Not sure if you need it to be resolution independent or not but I've put that in there.
If you need a set number of columns in the grid then just change gridColumns to be a fixed integer.
float gridItemWidth = 225.00;
float gridItemHeight = 225.00;
-(int)gridColumns {
NSRect frame = [self frame];
return (int)frame.size.width / (gridItemWidth);
}
-(int)getxOffset:(int)i {
int xPadding = 10;
return ((i % [self gridColumns]) * (gridItemWidth + xPadding));
}
-(int)getyOffset:(int)i {
int yPadding = 20;
return (floor(i / [self gridColumns]) * (gridItemHeight + yPadding));
}
Then basically in your loop you call getxOffset and getyOffset for the index of your loop to get the position of the grid.
I have manually set the x and y paddings in there to be 10 and 20, but you can set them to whatever you need.
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;
}