A script to draw, fill and group triangles in Livecode? - polygon

Appreciate any help in coming up with a Livecode script chunk to draw and fill a group of equilateral triangles.
I'm working on an open source app that helps people create and share stories with a fractal pattern.
A key challenge is drawing triangles that will represent the following elements of a story:
Attractor
Challenge
Opportunity (a state change to resolve the tension)
Strategy
Test
Decision
Each of the six standard story elements above will be displayed in the app as an equilateral triangle. Each element, in turn, will be associated with a distinctive color – yellow, red, orange, purple, blue, or green.
I'd love for a Livecode script to draw six triangles that fit together – much like pie slices – to form a hexagon that represents the whole narrative.
The transparency (blendlevel) of each colored segment will indicate the degree to which the story's author(s) – or invited reviewers – consider that element of the story to be complete.
My hope is to come up with a script in Livecode that will:
rapidly draw six triangles to form a hexagonal shape
fill each triangle with its associated color (each color will have an initial blendlevel of an almost transparent 90 percent)
assign a unique short name to each of the six triangles, based on the name of its fill color
group the six triangles so that they can be dragged together to new locations on the screen.
Are there any scripts (or chunks) that can help on this? Deeply appreciate any sample code or links to help shorten my Livecode learning curve.
Best,
Mark Frazier
====== Progress Update! ====== [August 2nd, 6 pm Eastern]
I've just found and adapted a polygon-generating script by Lloyd Rieber of Univ. of Georgia that creates hexagons. Is there a way to tweak it, so that it can create an equilateral triangle that can then be copied and rotated to fill out the hexagon?
on mouseUp
global tpoints
if exists(grc "HexagonCanvas" of this card) then delete grc "HexagonCanvas"
lock screen
create grc "HexagonCanvas"
set the loc of grc "HexagonCanvas" to "140,140"
set the opaque of grc "HexagonCanvas" to true
-- resize the new grc
get the rect of grc "HexagonCanvas"
add 80 to item 4 of it
set the rect of grc "HexagonCanvas" to it
put the topleft of grc "HexagonCanvas" into TL
put the topright of grc "HexagonCanvas" into TR
put the bottomleft of grc "HexagonCanvas" into BL
put the bottomright of grc "HexagonCanvas" into BR
put the width of grc "HexagonCanvas" into twidth
put the height of grc "HexagonCanvas" into theight
put trunc(twidth/4) into twidthquart
put trunc(theight/2) into theighthalf
#=========set the points for the "free" hexagon polygon==================
put empty into tpoints
put (item 1 of TL + twidthquart, item 2 of TL) into tpoints
# for the first line of tpoints "put into"
put Cr& (item 1 of TL, item 2 of TL + theighthalf) after tpoints
put CR& (item 1 of BL + twidthquart, item 2 of BL) after tpoints
put CR& (item 1 of BR - twidthquart, item 2 of BR) after tpoints
put Cr& (item 1 of BR, item 2 of BR - theighthalf) after tpoints
put CR& (item 1 of TR - twidthquart, item 2 of TR) after tpoints
put CR& (item 1 of TL + twidthquart, item 2 of TL) after tpoints
set the points of grc "HexagonCanvas" to tpoints
set the style of grc "HexagonCanvas" to "polygon"
set the backgroundColor of grc "HexagonCanvas" to blue
set the blendlevel of grc "HexagonCanvas" to "60"
choose browse tool
end mouseUp

The hardest part of this is drawing on the fly. You can certainly write a routine that will create your hexagonal pie, but it is better to draw this once and simply show or hide it.
The thing itself will be a group of six triangles, each of which can be addressed and have its properties set, color, blendLevel, etc.
If you need multiple copies of this gadget, you can clone the group, and rename both it and its triangle components at will.
One caveat. If you do proceed in this way, you must be aware that, for groups alone among all object classes, the keyword "last" is not stable. So your ability to reference this new group (set the name of the last group to "yourNewGroupname") is limited in that way. There is a workaround, using the template group, however, that works just fine. I recommend that you read the user notes in the dictionary under "last":
----The "last" keyword is not stable when referring to groups. So if one creates several groups, referencing the "last" group may not return the group actually created last. Using the "templateGroup" is a workaround, since when creating a new group one can, for example, set the name of the templateGroup to something unique, and be able to find the last group by name. Also, trapping the "newGroup" message with an appropriate script can be used to find the last group.
Hope this helps...
EDIT.
Are you familiar with the pertinent properties? The "backColor" to set the color, the "blendLevel" to set, well, the blendLevel, etc? Have you ever created a graphic like a triangle, and named it? Have you ever grouped objects?

Very industrious. Really.
I meant to create a triangle graphic using the polygon tool. You can set the number of sides of the graphic to 3 and name it, say "t1". You may have to adjust it to appear as an equilateral. This is now a full fledged object, and can be duplicated five times. Each new object can be named accordingly, ("t2", "t3", etc) and rotated so that you can assemble them all into a nice hexagon.
Now you can set the backColor and blendLevel of each graphic as you wish. Make sure that each graphic has its "opaque" property set to "true". If you group the six, you can clone new groups, but you have to manage the names of the offspring triangles.
Back to your earlier effort. You can see that even if you created a nice graphic using lines, there would be no easy way to isolate individual triangular sections. The polygon object fixes this nicely.
Craig

Reference
http://en.wikipedia.org/wiki/Equilateral_triangle
Iteration step
I took the script you found and with some light tweaks it works nicely. There is a
polygon polygonName, px, py, pColor
script which is called 4 times by a mouse up script. It draws 4 hexagons in different colors.
The polygon script does not live up to its name as it can only draw hexagons.
And then a mouseup script which uses the triangle script six times.
on mouseup
polygon "hex1", 100, 300, "green"
polygon "hex2", 240, 300, "yellow"
polygon "hex3", 380, 300, "red"
polygon "hex4", 520, 300, "brown"
end mouseup
on polygon polygonName, px, py, pColor
global tpoints
local TL
local TR
local BL
local BR
local twidth
local theight
local twidthquart
local theighthalf
if exists(grc polygonName of this card) then delete grc polygonName
lock screen
create grc polygonName
set the loc of grc polygonName to px,py
set the opaque of grc polygonName to true
-- resize the new grc
get the rect of grc polygonName
add 80 to item 4 of it
set the rect of grc polygonName to it
put the topleft of grc polygonName into TL
put the topright of grc polygonName into TR
put the bottomleft of grc polygonName into BL
put the bottomright of grc polygonName into BR
put the width of grc polygonName into twidth
put the height of grc polygonName into theight
put trunc(twidth/4) into twidthquart
put trunc(theight/2) into theighthalf
#=========set the points for the "free" hexagon polygon==================
put empty into tpoints
put (item 1 of TL + twidthquart, item 2 of TL) into tpoints
# for the first line of tpoints "put into"
put Cr& (item 1 of TL, item 2 of TL + theighthalf) after tpoints
put CR& (item 1 of BL + twidthquart, item 2 of BL) after tpoints
put CR& (item 1 of BR - twidthquart, item 2 of BR) after tpoints
put Cr& (item 1 of BR, item 2 of BR - theighthalf) after tpoints
put CR& (item 1 of TR - twidthquart, item 2 of TR) after tpoints
put CR& (item 1 of TL + twidthquart, item 2 of TL) after tpoints
set the points of grc polygonName to tpoints
set the style of grc polygonName to "polygon"
set the backgroundColor of grc polygonName to pColor
set the blendlevel of grc polygonName to "60"
choose browse tool
end polygon
Next iteration step
To continue various ways are possible.
An easy to follow way would be to modify the polygon script so that it works on triangles instead of a hexagon. As parameters it needs the position of the triangle (following a "clock dial convention or giving the sector in degrees)
Coordinates
(-r/2 ,h) (r/2,h)
-r/0 0 r/ 0
(-r/2 ,h) (r/2,h)
r = radius
h = height
h*h + (r/2)*(r/2) = r*r
Code which draws six triangles
`
on mouseUp
global tOffset
put 140 into tOffset
triangle "triangle1", -50,100, 0,0, -100, 0, "red"
triangle "triangle2", 0,0, -50, 100, 50,100, "green"
triangle "triangle3", 50, 100, 100, 0, 0,0, "blue"
triangle "triangle4", 0, 0, 100, 0, 50, -100, "yellow"
triangle "triangle5", 0, 0, 50, -100, -50, -100, "orange"
triangle "triangle6", 0, 0, -50, -100, -100, 0, "purple"
end mouseUp
on triangle polygonName, pax, pay, pbx, pby, pcx, pcy, pColor
global tpoints
global tOffset
if exists(grc polygonName of this card) then delete grc polygonName
lock screen
create grc polygonName
set the loc of grc polygonName to pax,pay
set the opaque of grc polygonName to true
put empty into tpoints
put (tOffset+pax, tOffset+pay) into tpoints
put Cr& (tOffset+pbx, tOffset+pby) after tpoints
put Cr& (tOffset+pcx, tOffset+pcy) after tpoints
set the points of grc polygonName to tpoints
set the style of grc polygonName to "polygon"
set the backgroundColor of grc polygonName to pColor
set the blendlevel of grc polygonName to "20"
choose browse tool
end triangle
Wiki
I made this a community wiki answer, so that people can easily paste in updated code.

Related

Why is lookAt not looking at specified vector?

I have this three js scene: http://codepen.io/giorgiomartini/pen/ZWLWgX
The scene contains 5 things:
Camera - Not Visible
origen (3D vector) - At 0,0,0.
objOne - Green
objParent - Red
CenterOfscene - Blue
objOne is a child of objParent. And ObjOne looksAt origen, which is a 3d vector at 0,0,0.
But the objOne instead of looking at the 0,0,0. where the origin vector is, It looks at objParent....?
Got any ideas?
What i want is the objOne to look at the 0,0,0. Which is the origen vector.
Any ideas why this is misbehaving? thanks.
THREE.SceneUtils.detach( objOne, objParent, scene );
THREE.SceneUtils.attach( objOne, scene, objParent );
var origen = new THREE.Vector3( 0, 0, 0 );
var render = function () {
objOne.lookAt(origen);
requestAnimationFrame( render );
xOffset += 0.01;
yOffset += 0.011;
zOffset += 0.012;
xOffsetParent += 0.0011;
yOffsetParent += 0.0013;
zOffsetParent += 0.0012;
camXPos = centeredNoise(-1,1,xOffset);
camYPos = centeredNoise(-1,1,yOffset);
camZPos = centeredNoise(-1,1,zOffset);
objOne.position.x = camXPos*4;
objOne.position.y = camYPos*4;
objOne.position.z = camZPos*4;
camParentXPos = centeredNoise(-1,1,xOffsetParent);
camParentYPos = centeredNoise(-1,1,yOffsetParent);
camParentZPos = centeredNoise(-1,1,zOffsetParent);
objParent.position.x = camParentXPos*10;
objParent.position.y = camParentYPos*10;
objParent.position.z = camParentZPos*10;
renderer.render(scene, camera);
};
render();
Object3D.lookAt() does not support objects with rotated and/or translated parent(s).
Your work-around is to (1) add the child as a child of the scene, instead, and (2) replace the child object with a dummy Object3D, which, as a child of the parent object, will move with the parent.
Then, in your render loop,
child.position.setFromMatrixPosition( dummy.matrixWorld );
child.lookAt( origin );
three.js r.75
Here is the corrected codepen:
http://codepen.io/anon/pen/oxGpPQ?editors=0010
Now the green disk rides around its parent (the red sphere) all while looking at the blue disk (or the 'origen' vector).
Uncomment lines 163 and 164 to make the camera be at the green disk's location and have the camera also look at the blue disk ('origen' vector) while it orbits its parent red sphere.
How I accomplished this is:
1. make parent Red Mesh
2. make dummyChild Object3D (this is an invisible math object)
3. make child Green Mesh
4. make origen centerOfScene Blue Mesh
5. attach parent, child, and centerOfScene mesh to Scene (not dummyChild though)
6. attach dummyChild to parent like so: parent.add(dummyChild);
In render function:
1. Move parent around with noise function (which offsets dummyChild)
2. Move dummyChild with another noise function (which revolves around its parent position, the center of dummyChild's world is its red parent's position)
3. Stick the green child mesh wherever the invisible dummyChild is. But since dummyChild is offset by red parent, we need to get it's world coordinates in relation to Scene, not its coordinates in red's world, so we use
child.setFromMatrixPosition(dummyChild.matrixWorld);
Notice its matrixWorld and not matrix - matrix holds its local system and matrixWorld holds its coordinated relative to the Scene or World coordinate system.
4. Use lookAt to make the green child disk 'lookAt' the blue centerOfScene Mesh which is at the origen vector or the center of the Scene.
Hope this helps! :)

How do I scale a container UIView's subviews' layout/size as I animate the container UIView?

Goal: to be able to animate a container-view's frame while it's subviews keep their original layout & scale in proportion to their container view.
Scenario:
Elements positioned via constraints/autolayout; within green container.
Green containerView's physical coordinates (frame/bounds) are adjusted per animation.
Members' compression & hugging properties are set to a low priority.
UIView.animateWithDuration(0, animations: {
self.bounds = myBounds
}) {(One) in
UIView.animateWithDuration(1, animations: {
self.frame = myFrame
}) {(Two) in
UIView.animateWithDuration(0.5, animations: {
self.frame = origFrame
// self.center = myCenter
}) {(Three) in
UIView.animateWithDuration(0.2, animations: {
self.frame = distantFrame
})
}
}
}
Here's the original layout:
I would like to have member element scale proportionally with their container view like this:
But the member elements (the one label 'Hello World!') don't adjust accordingly as their green containerView animates to a square in the upper left-hand corner:
How do I keep a UIView's members' layout in proportion to the prevailing their prevailing container view's frame?
Note: This would apply to any type of member (UIView, UITextView, ...etc.); for simple position/layout & transformation (pivot) animations.
In your example, you have a green background view (BG) and a hello world view (HW), and you want HW to scale in proportion to BG.
You can achieve this easily:
Open the Utilities pane in Xcode (top rightmost icon), and the Document outline (bottom left icon of storyboard).
Let’s assume that HW is already centered in BG, i.e. that you already set the alignment constraints for HW center horizontally and vertically in container.
Now, select BG as well as HW in the Document outline, and click the „Pin“ icon bottom right. It will offer the constraints „Equal widths“ and „Equal heights“. Activate both.
After these constraints have been created, open one of them in the Document outline. The utilities pane will then show the Equal Width constraint with the 2 views and a Multiplier field.
In the Multiplier field, you can enter the required proportions for the selected dimension, e.g. 1:3. This will fix the proportion for the selected dimension.
For the other dimension of course analogously. Of course you had then to update the frame of HW.
Here is an example:

JavaFX - Background insets for custom shapes

How is the -fx-background-insets value evaluated if the node's shape is not rectangle, i.e. there are no -meaningful- top-right-bottom-left sides? (The question also arises for -fx-border-width etc.)
What I am trying to achieve is to have a Pane having triangle shape with different border widths on each side.
.triangle-pane {
-fx-background-color: outer-color, inner-color;
-fx-shape: "M 0 4 L 10 1 L 10 7 z";
-fx-background-insets: 0, ?; // what to write here?
}
If I write a single value, it works as expected. If I write more, it behaves weird. I could not figure it out. Any help is appreciated.

Qt scene item group bounding rect did not follow rotation

As title clues, I tried to rotate group bounding rect by rotating the group itself nor by iteration of child items.
Do I need some kind of refresh for group to boundig rect adjust the shape as the view shows it?
Snippet for PySide :
R1 = scene.addRect(itemGroup.boundingRect())
R1.setPos(itemGroup.pos())
scene.addRect(itemGroup.boundingR())
# case 1 - Rotate group through iteration
for item in itemGroup.childItems() :
item.rotate(90)
# case 2 - Rotete whole group
itemGroup.rotate(90)
R2 = scene.addRect(itemGroup.boundingRect())
R2.setPos(itemGroup.pos())
it's because bounding rect in your case is local to an item, so rotation is not changing it. you should map rect to scene to get rect position in global coordinates

Boxed label with background color

Howto plot a boxed label with a specific background color? (Like the legend box)
Do you mean something like:
LABEL="label in a box"
set obj 10 rect at 0,0 size char strlen(LABEL), char 1 fc rgb "cyan"
set label 10 LABEL at 0,0 front center
plot sin(x)
Here's a link to gnuplot's demo where I got the idea.
Of course, you can make the size of the box slightly bigger -- I find that it makes things look a little nicer:
set obj 10 rect at 0,0 size char strlen(LABEL)+1, char 1.5 fc rgb "cyan"
But that's up to you.

Resources