ID:154302
 
I am currently in 11th Grade Geometry and loving every minute of it!(that wasnt sarcasm, i like math, me = nerd!)

Anyways, Triangles are cool, they are COOL! Well today i was trying to write a little proc that you could pass 5 arguments to, and would display a triangle onto the screen.

example:
proc
showtriangle(atom/O as obj,a as num,b as num,c as num,duration as num)
//O: the atom to make up the triangle
//A: the first length, or angle of the triangle
//B: the second length, or angle of the triangle
//C: the third length, or angle of the triangle
//Duration: Length of time to display the triangle


I was trying to figure out the best method, either declaring the lenghts of each side, or the degree's of each angle. I couldnt make up my mind, so i decided to do something like this...

proc
showtriangle(atom/O as obj,atom/a,atom/b,atom/c,duration as num)
//O: the atom type to make up the triangle
//A: an atom on the map, using locate(x,y,z)
//B: "" ""
//C: "" ""
//Duration: Length in time to display the triangle

This turned out to be much better, since all we have to do is declare three spots on the map using the locate() proc for our arguments in the proc call!

I figured i would need some of the following things to happen within the proc:

1. Determine the distance between each point
2. Determine the mid point of each side of the triangle
3. Determine the center of the triangle

all three of those things could easily be done by the following:

#1:
var/dist1 = get_dist(a,b)
var/dist2 = get_dist(a,c)
var/dist3 = get_dist(b,c)

#2:
var/half1 = round(dist1/2)
var/half2 = round(dist2/2)
var/half3 = round(dist3/2)

#3:
I had a little trouble with this, and I havent quite come up with a perfect method.

One major problem that i was concerned with during the entire designing of this, was the fact that some triangles could not be correctly displayed due to byond's tile based system. This was because you would sometimes need an object to be displayed "between" the lines....

I thought about making some proc, that uses missile some how, that just shoots a line from point a to b and so on. But that didnt turn out so well :(

So, im considering also making a crap load of icon states of each possible situation, or using the new icon datum to handle it via sliding and etc....

Then I was thinking about the next possible situations to include into the proc:

1. Determine (somehow) if the sum of the angles equal 180. This is true of all triangles.

< stands for angle sign


2. Determine if the sum of the lengths of any two sides added together is greater than the other remaining side. This is true of all triangles.

_ stands for line segment sign
A + B > C
A + C > B
B + C > A


3. Determine if any one of the sides is 90 degress, to make some of the processing easier on us(we know that one of the angles is 90 degress, and that two of the points go direction straight out from the 90 angle.)

These things would be considered for later, since they are basically checks to see if the user hasnt tried inputing an invalid triangle.

I was hoping that someone could send me even further down the line of understanding on this topic, so that i may learn how to show objects "between" the lines simpler, and so that my damn triangle effect will work!

FIREking
FIREking wrote:
> proc
> showtriangle(atom/O as obj,atom/a,atom/b,atom/c,duration as num)
>


Using the points of the triangle is definately the way to go. If you used the lengths or angles, you could be describing a triangle of the same shape anywhere in your world skewed at any angle.

I figured i would need some of the following things to happen within the proc:

1. Determine the distance between each point
2. Determine the mid point of each side of the triangle
3. Determine the center of the triangle

all three of those things could easily be done by the following:

#1:
var/dist1 = get_dist(a,b)
var/dist2 = get_dist(a,c)
var/dist3 = get_dist(b,c)

In DM, get_dist() doesn't return the true geometric distance between two points. You'll have to define a new proc for true distance:

proc/true_distance(atom/A, atom/B)
return sqrt((A.x-B.x)**2+(A.y-B.y)**2+(A.z-B.z)**2)

#2:
var/half1 = round(dist1/2)
var/half2 = round(dist2/2)
var/half3 = round(dist3/2)

That will tell you half the distance, but it won't tell you anything useful about the midpoint. Here is an example proc that returns the turf halfway between two atoms:

proc/midpoint(atom/A, atom/B)
return locate(round((A.x+B.x)/2,1), round((A.y+B.y)/2,1), round((A.z+B.z)/2,1))

(The round(*,1) is very important so that it rounds instead of simply truncating the decimal.)

#3:
I had a little trouble with this, and I havent quite come up with a perfect method.

I don't recall ever calculating the "center" of a triangle. Do you have a definition for it?

Off hand, I would think you could find the center by cacluating the line from each angle to the midpoint of the opposite side, then find the intersection of the three lines. I don't know if they will all intersect in the same point, and I really don't feel like doing a proof for it if you have the information available.

One major problem that i was concerned with during the entire designing of this, was the fact that some triangles could not be correctly displayed due to byond's tile based system. This was because you would sometimes need an object to be displayed "between" the lines....

Given the points, you can calculate the line for each side. To see if something is inside the triangle, cycle through each line and test if the object is on the same side of the line as the opposite angle. If the object fails any of the three tests, it's outside the triangle.

If you want to fill the triangle, get a block() the include the triangle (by getting the lowest and highest x and y values from the points given) and test each turf in the block to see if it's inside the triangle.


So, im considering also making a crap load of icon states of each possible situation, or using the new icon datum to handle it via sliding and etc....

Perhaps you could make a partially black/partially mask block, then turn() and shift() it to the right location and use icon addition to add it to the triangle icon. That way your triangle proc can use any icon without requiring ridiculous numbers of icon_states.


Then I was thinking about the next possible situations to include into the proc:

1. Determine (somehow) if the sum of the angles equal 180. This is true of all triangles.

2. Determine if the sum of the lengths of any two sides added together is greater than the other remaining side. This is true of all triangles.


If you define the triangle by the atomic points, you'll never have have to worry about either of these. You can't input an invalid triangle because any three (non-colinear) points defines a triangle. If the points are colinear, these rules are stile valid, but your triangle just became a line segment.


3. Determine if any one of the sides is 90 degress, to make some of the processing easier on us(we know that one of the angles is 90 degress, and that two of the points go direction straight out from the 90 angle.)


It would only make it easier if the angles correspond to the x and y axis. If I have a 90 degree angle that is 15 degrees clockwise from the x axis, knowing it's a right angle won't help draw it.


I was hoping that someone could send me even further down the line of understanding on this topic, so that i may learn how to show objects "between" the lines simpler, and so that my damn triangle effect will work!

Well, hope it helped. The notes above on checking something inside the triangle should probably be limited to checking it if the triangle is all on one z level. If not, you'll have to see if the object is even in the same plane with the triangle!

As you can probably tell. I enjoyed geometry too. ;)
In response to Shadowdarke
OH GOD NOT YOU ASWELL FIREKING!!!!!!!! i hate maths even though i'm good at it.
uhm.. just a thought @.@

Everyone knows that triangles are the basis of 3d graphics ne? If you could build a byond engine to do triangles of different sizes, shapes, and colours, preferably solid colours, and so you could place multiple ones on tiles / between tiles (overlays and rgb maybe? O.o; ) then you could concievably create a psudo polygon engine in byond O.o;;;;;

Just something I thought Id point out. It wouldnt be playable (cept for turn based first person rpgs and such) but itd be pretty interesting as a tech demo ^^;;

Elorien
In response to Shadowdarke
Shadowdarke wrote:

Using the points of the triangle is definately the way to go. If you used the lengths or angles, you could be describing a triangle of the same shape anywhere in your world skewed at any angle.

Yeah, I figured that after a little bit of thinking. I also considered doing circles where you give a x and a y variable, where x is the height, and y is the width. Then a circle is formed around this "cross", the middle being the point where x and y intersect each other(i think they would bisect each other too, if its a perfect circle).


In DM, get_dist() doesn't return the true geometric distance between two points. You'll have to define a new proc for true distance:

proc/true_distance(atom/A, atom/B)
return sqrt((A.x-B.x)**2+(A.y-B.y)**2+(A.z-B.z)**2)

Yeah, I figured this. But it does return the number of spaces between the points, and that could be very useful as byond doesnt use pixel movement, its tile based.

That will tell you half the distance, but it won't tell you anything useful about the midpoint. Here is an example proc that returns the turf halfway between two atoms:

How so? I figured half the distance from point a to point b would be the midpoint? If not, i planned on using the distance formula!

proc/midpoint(atom/A, atom/B)
return locate(round((A.x+B.x)/2,1), round((A.y+B.y)/2,1), round((A.z+B.z)/2,1))

(The round(*,1) is very important so that it rounds instead of simply truncating the decimal.)

I don't recall ever calculating the "center" of a triangle. Do you have a definition for it?

You could some how use medians of the triangle, one for each angle, but im not sure how easy that would be in byond.

Off hand, I would think you could find the center by cacluating the line from each angle to the midpoint of the opposite side, then find the intersection of the three lines. I don't know if they will all intersect in the same point, and I really don't feel like doing a proof for it if you have the information available.

Given the points, you can calculate the line for each side. To see if something is inside the triangle, cycle through each line and test if the object is on the same side of the line as the opposite angle. If the object fails any of the three tests, it's outside the triangle.

Well what i meant was, if you have a line that doesnt go exactley diagonal(NORTHWEST), then you would have problems drawing a connection line. What im wanting to do uses entire 32x32 atoms for each point and to connect those points. I didnt want anything like a real pixel triangle, just a simple tile based triangle.

If you want to fill the triangle, get a block() the include the triangle (by getting the lowest and highest x and y values from the points given) and test each turf in the block to see if it's inside the triangle.

Perhaps you could make a partially black/partially mask block, then turn() and shift() it to the right location and use icon addition to add it to the triangle icon. That way your triangle proc can use any icon without requiring ridiculous numbers of icon_states.

I'm not to keen on what you mean here, how would you do this without edges of the icons that you used going over the triangle?

If you define the triangle by the atomic points, you'll never have have to worry about either of these. You can't input an invalid triangle because any three (non-colinear) points defines a triangle. If the points are colinear, these rules are stile valid, but your triangle just became a line segment.

Good point!

It would only make it easier if the angles correspond to the x and y axis. If I have a 90 degree angle that is 15 degrees clockwise from the x axis, knowing it's a right angle won't help draw it.

Another good point, but i did figure it would speed up processing if we did try to find out facts about the triangle first, so the number of lines is less and the code runs faster, no biggie here though.

Well, hope it helped. The notes above on checking something inside the triangle should probably be limited to checking it if the triangle is all on one z level. If not, you'll have to see if the object is even in the same plane with the triangle!

As you can probably tell. I enjoyed geometry too. ;)

Thanks for replying to my post!

FIREking
In response to Deadman Walking
ya I'm pretty good at math but English isn't my fortay.
In response to JonSnow13
JonSnow13 wrote:
ya I'm pretty good at math but English isn't my fortay.

I can tell!

"Ya, I'm pretty good at math, but English isn't my best subject."

(Note: I didn't know the real meaning of "fortay", nor its spelling, but I could figure out its meaning by the context of your sentence.)

FIREking
In response to FIREking
FIREking wrote:
Yeah, I figured that after a little bit of thinking. I also considered doing circles where you give a x and a y variable, where x is the height, and y is the width. Then a circle is formed around this "cross", the middle being the point where x and y intersect each other(i think they would bisect each other too, if its a perfect circle).

We'll have to start a separate topic for ellipses when you want to talk about them. ;)


In DM, get_dist() doesn't return the true geometric distance between two points. You'll have to define a new proc for true distance:

proc/true_distance(atom/A, atom/B)
return sqrt((A.x-B.x)**2+(A.y-B.y)**2+(A.z-B.z)**2)

Yeah, I figured this. But it does return the number of spaces between the points, and that could be very useful as byond doesnt use pixel movement, its tile based.


Even pixel based movement is in essence tile based. The tiles are merely 1x1 instead of 32x32. If you want to use the distance for any sort of geometric figures, you'll need the geometric distance, not step distance. You can't mix and match the two types of distance in your procs, or your shapes will come out all wrong. Using BYOND step distance, a circle is a square.

When working with geometric shapes for your effects, think of the entire tile as a point. If you think of it that way, it will be easy to draw lines of tiles from point A to point B.


I figured half the distance from point a to point b would be the midpoint? If not, i planned on using the distance formula!


If I have a line from (1,1,1) to (17,5,1), the distance is roughly 16 tiles. Using your method to find the midpoint, you would divide that number in half and arrize at the answer of 8. What does 8 tell you about a turf? It's 8 away! That's great, but there are many turfs that are 8 away from (1,1,1).

Instead use the midpoint proc on that coordinate pair:

proc/midpoint(atom/A, atom/B)
return locate(round((A.x+B.x)/2,1), round((A.y+B.y)/2,1), round((A.z+B.z)/2,1))

returns the turf at (9,3,1) that is a useful point that means something. It is the same distance from (1,1,1) as it is from (17,5,1), exactly halfway between them. Do the math and you'll see it's about 8 from each endpoint.


I don't recall ever calculating the "center" of a triangle. Do you have a definition for it?

You could some how use medians of the triangle, one for each angle, but im not sure how easy that would be in byond.

That's roughly what I said in my original post. A line from the vertex of the angle to the midpoint of the opposite line bisects that angle.


Given the points, you can calculate the line for each side. To see if something is inside the triangle, cycle through each line and test if the object is on the same side of the line as the opposite angle. If the object fails any of the three tests, it's outside the triangle.

Well what i meant was, if you have a line that doesnt go exactley diagonal(NORTHWEST), then you would have problems drawing a connection line. What im wanting to do uses entire 32x32 atoms for each point and to connect those points. I didnt want anything like a real pixel triangle, just a simple tile based triangle.

I understand exactly what you mean. I don't think you understand my idea here. Using each 32 x 32 atom as if it were a single point, you can calculate the lines for turfs just as you could for pixels. I'm talking about atom x and y values, not icon x and y values. You can still use the lines and opposite points to determine if something is inside the triangle.


Perhaps you could make a partially black/partially mask block, then turn() and shift() it to the right location and use icon addition to add it to the triangle icon. That way your triangle proc can use any icon without requiring ridiculous numbers of icon_states.

I'm not to keen on what you mean here, how would you do this without edges of the icons that you used going over the triangle?


I'm talking about a possible method to turn any icon fed to your triangle proc into a pixel perfect triangle. It would be a purely graphical effect, and take a lot of cpu power to perform all the icon calculations, but it would be a lot easier than providing every possilble case in icon_states, like you seemed to be planning on when I read your original post.
In response to FIREking
Forté = Strength

[Edit] Just being a smartass... Don't mind me... : )
In response to JonSnow13
Hey! What do you have against me?!

j/k :p

Math goes in cycles for me, I like it then I hate it, I like it then I hate it. Right now I hate my math class because the concepts are hard to visualize, the book isn't very helpful, and the teacher isn't the greatest.

I'm getting it slowly but surely, I just don't solve the problems as fast as I'd like to. Here's an example:

Find h(x,y) = g(f(x,y)) and the set on which h is continuous.

g(t) = (sqrt(t) - 1)/(sqrt(t)+1)
f(x,y) = x^2 - y

It's starting to come a little more naturally, I think just need to go talk to the teacher to get the concepts solidified.