Hi, I've been secretly using AGS for years and I love being a ghost in the forums from time to time, but now I'm really stumped. I called this a Beginner's Question because I'm hoping a whiz can think of a clever work-around. This is going to sound very pathetic and probably for good reason, but here goes:
SKIP IF IN HURRY {
I like to do this thing (on paper using a compass) where I assign each of the 26 letters in the alphabet a number, where that number is an amount of degrees (as in a circle). That way each letter can be represented by a geometric arc (an incomplete circle). Then I take a bit of text--I like to use classical Chinese poetry--and translate it into a single image by beginning at a central point and drawing each arc (letter) in succession so that the final product looks like a bunch of concentric circles, like a record. Then I hang it on my wall and cry. Actually it's neater than it sounds and I never cry.
}
I thought it would be easy to make a program in AGS where I could perhaps Text Parser a single letter at a time, where submitting the letter resulted in a function which would visually adjust the Room or perhaps the Raw Draw Room Background surface using high-res coordinates, or something! I hit the forums to find out about Raw Draw and maths.sin/cos and I have one three questions:
(1.) How can I draw just one line segment on the draw surface with a curvature (not a real circle) based on a truncated three or four-digit pi? Another forum post about a clock program hinted that sin/cos might be used instead of DrawCircle to achieve just an outline or a close facsimile, but it did not address that process and I need remedial math...
(2.) If I can, how many curves can I draw at once without slowing too much? 100 would probably get me a haiku but I'd be really excited about thousands in higher resolution
(3.) Would saving the game save the raw draw display state?
I'm not sure I can use methods involving pre-rendered sprites since each arc (letter) needs to have a higher radius depending on where it exists in a sequence (text). I thought of using room scaling...but I'm not sure I can have that many areas and baselines in a room at once, since that would probably have to be characters huh...
I have no code to share because I can't determine a single method to achieve this. If I just had an example of how to draw function one curved line I could take it from there. If anyone wants to check it out, I did make a sweet AGS game that functions like a running flash scroller (burrito bison, toss the turtle etc). Thanks geniuses!
JB
Take a look at this picture (http://debraborkovitz.com/wp-content/uploads/2011/12/dilated-circle-with-trig-functions-and-triangle.png). Observe:
x = r * cos(theta);
y = r * sin(theta);
The most common way to draw curves on the computer is to divide them into very short bits (as small as one pixel or even less) and draw straight lines between each bit. So if a certain letter should be represented by an arc from theta1 to theta2 with radius r, a first approximation is to calculate the x,y coordinates for each angle, and then just draw a line between them. If that's not good enough, calculate the x,y coordinates for theta3 = (theta1+theta2)/2 and draw lines through this point. Keep subdividing until it looks smooth (i.e. the coordinates are adjacent pixels).
This will do the trick, though my feeling is that it will be pretty slow. There are no doubt ways to make it run much faster; how best to optimize it would depend on how exactly it should run (for example if you want to dynamically "scroll" through the text by adjusting the radii on the fly).
It should be said that AGS is probably not ideal if you want to make something you can print out. For that, the best thing would be something that wrote a vector-based image.
Thanks!
Slowdown shouldn't be an issue unless you want to draw the curves "in real time". Generating the final image is a one-time process, so even if it takes half a minute, that shouldn't be a problem, right?
Afaik, saving the game will conserve the room background; on the other hand, wouldn't the program draw the curves to a quadratic DynamicSprite and save the result to the hard drive anyway? Isn't this just about converting text to an image, file by file?
Quote from: Khris on Wed 09/01/2013 13:25:42
Generating the final image is a one-time process, so even if it takes half a minute, that shouldn't be a problem, right?
In a really basic way, reading Arc cypher is conceptually similar to reading information on a compact disc or a record--by starting at a central point and looking for anomalies in successive circles. ATM I'm just making a converter that goes from text to Arc and potentially back (speed is not a porb), but if I wanted to make a reader that went from Arc x/y data to say, a constantly updating source (animation?) I would worry about speed. If I could do that, I could (with a hefty 3rd-party program) convert image data for a GIF, "Back to the Future" or even a live webcam feed into a Mega-Arc and then read it. If speed weren't an issue I could watch laser discs in AGS (may not be true).Quote from: Khris on Wed 09/01/2013 13:25:42
...draw the curves to a quadratic DynamicSprite and save the result to the hard drive
You're my new hero. I'm starting to probe beyond my scripting comfort zone, and it's probing back. I'm still wrapping my brain around an undo button (backspace) based on storing x,y values for the end of each arc in an (dynamic?) array. Speaking of which:
(1.) Dynamic Arrays can only be declared one time after which any adjustment to the number of variables in the array wipes the contents of the array? Is that correct?
I'm trying to establish undo levels by storing one x and y value for each arc (not each Draw equation), where the function that renders each arc only needs to know where the last arc ended in order to adjust radius and starting x/y. Of course, I also need to store a 1-26 number value for each arc to denote it's letter, so should I/can I run three Dynamic arrays (x, y, and alpha #) or should I use a struct and regular array and thus cap the max number of arcs from the start? I want to store three int's per arc and leave the limit open to test how many arcs I can play with at once.
[Edit] Doh--limit still 500 globalInts?
I'm having a hard time understanding what you were saying about an updating source and stuff.
Do you actually mean to code a program that goes over a livestream pixel by pixel, detecting arcs and converting them into text again? Because not only is AGS simply not capable of doing this, it sounds like a job even Skynet would have problems with.
Regarding GlobalInts, those are thankfully a thing of the past. You can declare any kind of global variable you like. There's the global variables pane (assuming you aren't actually still using AGS 2.X), but you can of course declare any variable in script like this:
// header
import int MyArray[10000];
// global script
int MyArray[10000];
export MyArray;
[edit] I'm using the newest version [/edit]
Quote from: Khris on Thu 10/01/2013 06:27:47
I'm having a hard time understanding what you were saying about an updating source and stuff.
That blurb was a joke. Snip!
I've never converted between radians and degrees before and I'm confused about the proper method. I get a float error: expected float variable after '=' in my global variables.asc area, which double clicking doesn't access since it throws at compile time.[edit] I was able to fix the FloatToInt bugs below and I pared it down to: undefined token "Canvas" which is the name of my sprite's draw surface. Am I not allowed to issue draw commands from a custom script to a surface in a room? Code is at line 25 [/edit]
// in PrepArc.asc, a script which is called upon submitting a letter in the prompt
function PrepArc(){
// establish desirable number of divisions (nodes for DrawLine curve illusion) based on radius and arc length
// CurLetter is an int from 1-26, also represents X/26ths of a full circle which will form that letter's arc
ArcDivisions=CurRadius*CurLetter;
// Divide that number of divisions by the length of the arc to determine Nodes per arc unit
ArcNodesPerUnit=(FloatToInt((ArcDivisions/CurLetter), eRoundNearest));
// 13.85 is approximately 1/26 of 360, NewNodeAngleAmt is a float global variable along with NewNodeAngleSum
// trying get these two floats to contain a number of degrees, Amt is amount of degrees between nodes in the 13.85 degree unit
NewNodeAngleAmt=(13.85/ArcNodesPerUnit);
// add the in-between-nodes angle to the angle of the x/y at the end of the previous arc (where the new arc starts)
NewNodeAngleSum=(NewNodeAngleAmt+CurAngleEnd);
// ArcReady observed by room's repexec
ArcReady=1;
}
//Now in WriteArc.asc, a script for doing the actual drawing of the line from one node to the next
function WriteArc(){
ArcReady=2;
NewStartX=(FloatToInt((CurRadius*cos(Maths.DegreesToRadians(CurAngleEnd))), eRoundNearest));
NewStartY=(FloatToInt((CurRadius*sin(Maths.DegreesToRadians(CurAngleEnd))), eRoundNearest));
// the following two lines appear as one in editor
Canvas.DrawLine(NewStartX, NewStartY, (FloatToInt((CurRadius*cos(Maths.DegreesToRadians(NewNodeAngleSum))), eRoundNearest)), (FloatToInt((CurRadius*sin(Maths.DegreesToRadians(NewNodeAngleSum))), eRoundNearest));
CurAngleEnd=NewNodeAngleSum;
ArcNodesDone+=1;
if (ArcNodesDone==ArcDivisions){
gPrompt.Visible=true;
BtnClr.Visible=true;
ArcReady=0;
}
}
I haven't solved the issue of what happens when 360 degrees turns over to 1 degree
, but right now I can't even add smaller angles properly. Bear with me here I know I'm bad at this
I have to convert my angle-storing float variables into radians, do the cosine and sine operations, then convert those answers into integers for use as x/y coordinates, right?
Custom scripts can only use variables that are declared inside or above them ("above" referring to the order of the scripts in the project tree).
If you want to use a pointer or variable in several scripts, declare it in the topmost, then export it and import it in the script's header. (Script headers are added to all subsequent scripts, including the global and room script, at compile time.)
So... I liked the idea and coded this myself :)
Result: http://i.imgur.com/Zoyn6.png
Exe: https://dl.dropbox.com/s/p1hjnbm8pt3mapr/Arcs.zip?dl=1
(press space to switch between alternating direction or not, left and right arrow keys to set whether arcs have same angle or length)
Source room script: http://pastebin.com/iQEx98Fq
I am not worthy *Repeated Wayne's World Supplication* you understand implicitly! That's exactly it and I can't believe that instead of me catching flack for being crazy, someone else wanted to give it a try. Thanks for that! So it looks like no big slowdown, and that looks like roughly 100 letters or so? Success! 8) 8) 8) :-D :-D :-D Cool to know so many nodes are possible too, I was being really conservative with nodes=radius*letternumber.
The option to switch direction is really cool and left/right arrow keys blows my mind. Mamma likey