• Advertisement

Archived

This topic is now archived and is closed to further replies.

advanced use of the IF statement

This topic is 5028 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey GDers! I have an extremely tedious task for you. I have an IF statement with a LOT of parentheses (29x2 pairs!). The problem is that my compiler (Borland C++ Builder 3) gives me errors ("Expression syntax", "If statement missing )" and "Compound statement missing }" ) Sound like a n00b problem? Perhaps it is and people use IF like this all the time, but is it possible to go overboard like I did here?
if( (
            ( (x1 <= x ) && (x2 => x) ) ||
            ( (x2 <= x) && (x1 => x) )
            ) && (
            ( (line->x1 <= x) && (line->x2 => x) ) ||
            ( (line->x2 <= x) && (line->x1 => x) )
            ) && (
            ( (y1 <= y) && (y2 => y) ) ||
            ( (y1 >= y) && (y2 <= y) )
            ) && (
            ( (line->y1 <= y) && (line->y2 >= y) ) ||
            ( (line->y1 >= y) && (line->y2 <= y) ) )
            ) {
                return true;
            }
This block of code checks that the bounds of x are within x1 and y1 and within line->x1 and line->x2, and that the bounds of y are within y1 and y2 and within line->y1 and line->y2. a) Is this a legal use of IF, and if so, why am I getting errors with it? b) Is there a simpler way of doing this? Cheers! Stay Clausal, Red Sodium

Share this post


Link to post
Share on other sites
Advertisement
sounds like you have a ")" that is missing somewhere.

Share this post


Link to post
Share on other sites
That''s the problem, I don''t. I have looked at my nested depths several times and they''re fine, AND when doing a search for "(" and ")" I get 29 each times. Certainly a weird problem...

Stay Clausal,

Red Sodium

Share this post


Link to post
Share on other sites
I checked with UltraEdit, and all your braces match. Maybe the problem is the places where you''re using => instead of >=. Sometimes the error message that''s given isn''t always an indication of what the real problem is.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Take off the last ) and it should work

Share this post


Link to post
Share on other sites
I produced this:


if (
(
(
(
x1 <= x
)
&&
(
x2 => x
)
)
||
(
(
x2 <= x
)
&&
(
x1 => x
)
)
)
&&
(
(
(
line->x1 <= x
)
&&
(
line->x2 => x
)
)
||
(
(
line->x2 <= x
)
&&
(
line->x1 => x
)
)
)
&&
(
(
(
y1 <= y
)
&&
(
y2 => y
)
)
||
(
(
y1 >= y
)
&&
(
y2 <= y
)
)
)
&&
(
(
(
line->y1 <= y
)
&&
(
line->y2 >= y
)
)
)
||
(
(
line->y1 >= y
)
&&
(
line->y2 <= y
)
)
)
) //remove this one i think

{ return true;
};


edit: Damn what a waste of time, and I was wrong.

[edited by - honayboyz on April 15, 2004 7:04:15 PM]

Share this post


Link to post
Share on other sites
No, but I''m a tester for Mission: Land!, Fusion Apple''s next game. Well, I helped out with a few things in Unga Bunga. I''m guessing you know this from the link my signature takes you to?

Stay Clausal,

Red Sodium

Share this post


Link to post
Share on other sites
quote:
Original post by red_sodium

b) Is there a simpler way of doing this?




If you could guarantee that x1 is always <= x2 (and same for the y's), then half of those cases would dissappear. You could always swap x1 and x2 to make it true.

You can break up the construction into some booleans to make it far more readable.

Here's my version of that thing:


bool within_x = ((x1 <= x ) && (x2 >= x)) || ( (x2 <= x) && (x1 >= x));
bool within_y = ((y1 <= y ) && (y2 >= y)) || ( (y2 <= y) && (y1 >= y));
bool within_line_x = ((line->x1 <= x ) && (line->x2 >= x)) || ( (line->x2 <= x) && (line->x1 >= x));
bool within_line_y = ((line->y1 <= y ) && (line->y2 >= y)) || ( (line->y2 <= y) && (line->y1 >= y));
return within_x && within_y && within_line_x && within_line_y;


[edited by - pinacolada on April 15, 2004 8:34:33 PM]

Share this post


Link to post
Share on other sites
I usually use some nifty(IMO) templates to simplify expressions such as these:


Order( &x1, &x2 ); //if x2 is less than x1, swap them

Order( &y1, &y2 );
Order( &line->x1, &line->x2 );
Order( &line->y1, &line->y2 );

if( IsBetween(x, x1, x2) &&
IsBetween(x, line->x1, line->x2) &&
IsBetween(y, y1, y2) &&
IsBetween(y, line->y1, line->y2)
{
return true;
}

Of course, if you can''t change the values of x1, x2, etc, than you can''t call Order on them.
One other thing I''d try is to a box test.

if( PointInBox( v, Box ) && // v is a 2d vector, with x, and y
PointInBox( v, LineBox) )
{
return true;
}

Share this post


Link to post
Share on other sites
Instead of testing with if and returning true, you can just return the result of the boolean evaluation.

As mentioned above you have mis-matched ()''s.

The code''s not pretty but it has to be somewhere, and you tried to make it readable. You should make functions for collision detection, so that in main code you have something like
if( within(point, square) )
//Blam!


What you call a line appears to actually be a segment, the difference is important for this type of code.

Share this post


Link to post
Share on other sites
Magmai: Not if he does other work first in the false case

It will probably be slower, and may be overflow-prone depending on your data, but you can also test between-ness like this:

if (((x - x1)*(x - x2)) < 0) { // between
} else if (((x - x1)*(x - x2)) == 0) { // equal to at least one of them
} else { // outside
}

Share this post


Link to post
Share on other sites
Why did you wrap every single expression such as "x1 <= x" within parenthesis? ( (x1 <= x ) && (x2 => x) ) could be just (x1 <= x && x <= x2). Anyway, do as Thrump said and use functions to simplify things like this. IsBetween can be defined just like the code you already use so you won''t need the Order-functions.

//use a template if you know anything about them
inline bool IsBetween(int x, int b1, int b2) {
return (b1 <= x && x <= b2) || (b2 <= x && x <= b1);
}

Share this post


Link to post
Share on other sites
Thanks folks. Yeah I do seem to have gone a little overboard with parentheses, it was mainly for readability (and it appears to have done the opposite). It works now, so I''m not too bothered about changing it, but I''ll make sure to take one of these options in future. I''m guessing that since my IF statement is working with logical AND and OR evaluations, there won''t really be anything faster, just more readable.

Here''s my final function, for anyone who actually cares:

return Intersection( line, x, y ) &&
( ( x1 <= x && x2 >= x ) ||
( x2 <= x && x1 >= x )
) && (
( line->x1 <= x && line->x2 >= x ) ||
( line->x2 <= x && line->x1 >= x )
) && (
( y1 <= y && y2 >= y ) ||
( y1 >= y && y2 <= y )
) && (
( line->y1 <= y && line->y2 >= y ) ||
( line->y1 >= y && line->y2 <= y ) );


Stay Clausal,

Red Sodium

Share this post


Link to post
Share on other sites
It could be faster to first check the crude bounds, then call Intersection() -- Now you''re doing vice versa. Remember that && is computed in left-to-right order, and if the left side returns false, the right side isn''t evaluated at all and the whole thing equals false. If Intersection() is an expensive function, it could be a lot faster to calculate it only if necessary.
quote:
there won''t really be anything faster
I wouldn''t be so sure about that.
quote:
just more readable.
As if that didn''t matter.

Share this post


Link to post
Share on other sites
I always need to call Intersection to return my x and y values (it is these that I perform bounds checking on).

Thanks for all the help folks, I''m done with it and moving on.

Stay Clausal,

Red Sodium

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
you could always try to prove the intersection false instead of true. the code would be easier to read.

Share this post


Link to post
Share on other sites

  • Advertisement