| MAS ETH ARCH/CAAD - 2005/06 - STUDENT PAGES Master of Advanced Studies in Architecture, Specialization in Computer Aided Architectural Design | 065-0005/6 Supervision: Prof. Dr. Ludger Hovestadt, Philipp Schaerer Chair of CAAD, ETH Zurich
assignment
pattern > > > sand | waves > > > final solutions 2D
| | example I click on image to see picture of laser cut model |
| | example II click on image to see picture of laser cut model |
| | example III click on image to see larger picture + movie of drawing process |
| | example IV click on image to see larger picture + movie of drawing process |
| | example V click on image to see larger picture + movie of drawing process |
| | example VI click on image to see larger picture + movie of drawing process |
| | example VII click on image to see larger picture + movie of drawing process |
| | example VIII click on image to see larger picture + movie of drawing process |
| | example IX click on image to see larger picture + movie of drawing process |
| | example X click on image to see larger picture + movie of drawing process |
plug-in
script
PROCEDURE SandWaves;
VAR
AreaQuest, DistPt1Set, DistPt2Set, DistPt3Set : INTEGER;
AreaX1, AreaY1, AreaX2, AreaY2, AreaX3, AreaY3, AreaX4, AreaY4 : REAL;
angle, density, intfer : REAL;
Disturb1, Disturb2, Disturb3 : BOOLEAN;
DistPtX1, DistPtY1, DistPtX2, DistPtY2, DistPtX3, DistPtY3 : REAL;
InCheck1, InCheck2, InCheck3, InCheck4 : BOOLEAN;
Stone1Rad, Stone2Rad, Stone3Rad : REAL;
Effect1, Effect2, Effect3 : REAL;
AreaX1ROT, AreaY1ROT, AreaX2ROT, AreaY2ROT, AreaX3ROT, AreaY3ROT, AreaX4ROT, AreaY4ROT : REAL;
DistPtX1ROT, DistPtY1ROT, DistPtX2ROT, DistPtY2ROT, DistPtX3ROT, DistPtY3ROT : REAL;
BorderPoly, Stone1, Stone2, Stone3 : HANDLE;
RadAng : REAL;
Diagonal :REAL;
MaxArrayX, MaxArrayY : LONGINT;
ArrayPt : DYNARRAY[,] OF POINT;
i, k : INTEGER;
XTemp, YTemp, YTemp1, YTemp2, YTemp3 : REAL;
dist1, dist2, dist3 : REAL;
DistField1, DistField2, DistField3 : REAL;
BEGIN
{######### SET AREA BY USER #########}
AreaQuest := IntDialog('Please select:
1 Define area by mouse.
2 Define area by keys.','1');
IF (AreaQuest = 2) THEN BEGIN
AreaX1 := RealDialog('Please define area to be filled!
Set X value of bottom left point:','0.00');
AreaY1 := RealDialog('Please define area to be filled!
Set Y value of bottom left point:','0.00');
AreaX3 := RealDialog('Please define area to be filled!
Set X value of top right point:','100.00');
WHILE (AreaX3 < AreaX1) DO BEGIN
IF (AreaX3 < AreaX1) THEN AreaX3 := RealDialog('X value of top right point must be higher than X value of bottom left point. Try again!','100.00');
END;
AreaY3 := RealDialog('Please define area to be filled!
Set Y value of top right point:','100.00');
WHILE (AreaY3 < AreaY1) DO BEGIN
IF (AreaY3 < AreaY1) THEN AreaY3 := RealDialog('Y value of top right point must be higher than Y value of bottom left point. Try again!','100.00');
END;
END;
IF (AreaQuest = 1) THEN BEGIN
GetRect(AreaX1,AreaY1,AreaX3,AreaY3);
WHILE (AreaX3 < AreaX1) OR (AreaY3 < AreaY1) DO BEGIN
IF (AreaX3 < AreaX1) THEN AlrtDialog('Sorry, X value of second point must be higher than X value of first point. Try again!');
IF (AreaY3 < AreaY1) THEN AlrtDialog('Sorry, Y value of second point must be higher than Y value of first point. Try again!');
GetRect(AreaX1,AreaY1,AreaX3,AreaY3);
END;
END;
{######### CREATE BORDER POLY #########}
PenFore(20000,20000,20000);
PenSize(140);
FillPat(0);
ClosePoly;
BeginPoly;
AddPoint(AreaX1,AreaY1);
AddPoint(AreaX1,AreaY3);
AddPoint(AreaX3,AreaY3);
AddPoint(AreaX3,AreaY1);
EndPoly;
BorderPoly := LObject;
ReDrawAll;
{######### SET OTHER PARAMETERS BY USER #########}
angle := RealDialog('Please enter angle of texture (in degrees):','45');
IF (angle > 360) OR (angle < -360) THEN BEGIN
WHILE (angle > 360) OR (angle < -360) DO BEGIN
angle := RealDialog('Angle value must be between -360 and 360! Set value again:','45');
END;
END;
density := RealDialog('Please choose density:
(Values between 0.1 (dense) and 10 (loose) recommended!)','1');
intfer := RealDialog('Please set interference:
(Values between 0 and 1 recommended!)','0.50');
{######### SET DISTURBANCE POINTS BY USER #########}
Disturb1 := YNDialog('Do you wish to set disturbance points?');
PenFore(30000,30000,30000);
PenSize(70);
FillPat(17);
IF Disturb1 = TRUE THEN BEGIN
DistPt1Set := IntDialog('Please select:
1 Set disturbance points by mouse.
2 Set disturbance points by keys.','1');
IF (DistPt1Set = 2) THEN BEGIN
WHILE (InCheck1 = FALSE) DO BEGIN
DistPtX1 := RealDialog('Set X value of first disturbance point:','10.00');
DistPtY1 := RealDialog('Set Y value of first disturbance point:','10.00');
InCheck1 := PtInPoly(DistPtX1,DistPtY1,BorderPoly);
IF InCheck1 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please set X and Y values again!');
END;
Locus(DistPtX1,DistPtY1);
Stone1 := LObject;
Stone1Rad := RealDialog('Set size of first disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX1-Stone1Rad,DistPtY1-Stone1Rad,DistPtX1+Stone1Rad,DistPtY1+Stone1Rad);
ReDrawAll;
Effect1 := RealDialog('Set shifting effect of first disturbance point:
(Values between 2 and 5 recommended!)','3.00');
Disturb2 := YNDialog('Do you wish to set another disturbance point?');
IF Disturb2 = TRUE THEN BEGIN
WHILE (InCheck2 = FALSE) DO BEGIN
DistPtX2 := RealDialog('Set X value of second disturbance point:','20.00');
DistPtY2 := RealDialog('Set Y value of second disturbance point:','20.00');
InCheck2 := PtInPoly(DistPtX2,DistPtY2,BorderPoly);
IF InCheck2 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please set X and Y values again!');
END;
Locus(DistPtX2,DistPtY2);
Stone2 := LObject;
Stone2Rad := RealDialog('Set size of second disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX2-Stone2Rad,DistPtY2-Stone2Rad,DistPtX2+Stone2Rad,DistPtY2+Stone2Rad);
ReDrawAll;
Effect2 := RealDialog('Set shifting effect of second disturbance point:
(Values between 2 and 5 recommended!)','3.00');
Disturb3 := YNDialog('Do you wish to set another disturbance point?');
END;
IF Disturb3 = TRUE THEN BEGIN
WHILE (InCheck3 = FALSE) DO BEGIN
DistPtX3 := RealDialog('Set X value of third disturbance point:','30.00');
DistPtY3 := RealDialog('Set Y value of third disturbance point:','30.00');
InCheck3 := PtInPoly(DistPtX3,DistPtY3,BorderPoly);
IF InCheck3 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please set X and Y values again!');
END;
Locus(DistPtX3,DistPtY3);
Stone3 := LObject;
Stone3Rad := RealDialog('Set size of third disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX3-Stone3Rad,DistPtY3-Stone3Rad,DistPtX3+Stone3Rad,DistPtY3+Stone3Rad);
ReDrawAll;
Effect3 := RealDialog('Set shifting effect of third disturbance point:
(Values between 2 and 5 recommended!)','3.00');
AlrtDialog('This should be enough - no more disturbance points!');
END;
END;
IF (DistPt1Set = 1) THEN BEGIN
WHILE (InCheck1 = FALSE) DO BEGIN
GetPt(DistPtX1,DistPtY1);
InCheck1 := PtInPoly(DistPtX1,DistPtY1,BorderPoly);
IF InCheck1 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please click again!');
END;
Locus(DistPtX1,DistPtY1);
Stone1 := LObject;
Stone1Rad := RealDialog('Set size of first disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX1-Stone1Rad,DistPtY1-Stone1Rad,DistPtX1+Stone1Rad,DistPtY1+Stone1Rad);
ReDrawAll;
Effect1 := RealDialog('Set shifting effect of first disturbance point:
(Values between 2 and 5 recommended!)','3.00');
Disturb2 := YNDialog('Do you wish to set another disturbance point?');
IF Disturb2 = TRUE THEN BEGIN
WHILE (InCheck2 = FALSE) DO BEGIN
GetPt(DistPtX2,DistPtY2);
InCheck2 := PtInPoly(DistPtX2,DistPtY2,BorderPoly);
IF InCheck2 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please click again!');
END;
Locus(DistPtX2,DistPtY2);
Stone2 := LObject;
Stone2Rad := RealDialog('Set size of second disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX2-Stone2Rad,DistPtY2-Stone2Rad,DistPtX2+Stone2Rad,DistPtY2+Stone2Rad);
ReDrawAll;
Effect2 := RealDialog('Set shifting effect of second disturbance point:
(Values between 2 and 5 recommended!)','3.00');
Disturb3 := YNDialog('Do you wish to set another disturbance point?');
END;
IF Disturb3 = TRUE THEN BEGIN
WHILE (InCheck3 = FALSE) DO BEGIN
GetPt(DistPtX3,DistPtY3);
InCheck3 := PtInPoly(DistPtX3,DistPtY3,BorderPoly);
IF InCheck3 = FALSE THEN AlrtDialog('Choosen point is not in defined area. Please click again!');
END;
Locus(DistPtX3,DistPtY3);
Stone3 := LObject;
Stone3Rad := RealDialog('Set size of third disturbance point:
(Values between 1 and 20 recommended!)','5.00');
Oval(DistPtX3-Stone3Rad,DistPtY3-Stone3Rad,DistPtX3+Stone3Rad,DistPtY3+Stone3Rad);
ReDrawAll;
Effect3 := RealDialog('Set shifting effect of third disturbance point:
(Values between 2 and 5 recommended!)','3.00');
AlrtDialog('This should be enough - no more disturbance points!');
END;
END;
END;
IF Disturb1 = FALSE THEN AlrtDialog('What a shame! You miss the best part...');
{######### ROTATE BORDER POLY AND DISTURBANCE LOCI (ANGLE) #########}
RotatePoint(AreaX1,AreaY1,-angle);
ReDrawAll;
GetPolyPt(BorderPoly, 1, AreaX1ROT, AreaY1ROT);
GetPolyPt(BorderPoly, 2, AreaX2ROT, AreaY2ROT);
GetPolyPt(BorderPoly, 3, AreaX3ROT, AreaY3ROT);
GetPolyPt(BorderPoly, 4, AreaX4ROT, AreaY4ROT);
GetLocPt(Stone1, DistPtX1ROT ,DistPtY1ROT);
GetLocPt(Stone2, DistPtX2ROT ,DistPtY2ROT);
GetLocPt(Stone3, DistPtX3ROT ,DistPtY3ROT);
{######### CREATE WAVES #########}
{### ALLOCATE DYNARRAY ###}
IF (angle >= 0) AND (angle < 90) THEN BEGIN
MaxArrayX := Trunc((AreaX3ROT - AreaX1ROT) / density);
MaxArrayY := Trunc((AreaY2ROT - AreaY4ROT) / density);
END;
IF (angle >= 90) AND (angle < 180) THEN BEGIN
MaxArrayX := Trunc((AreaX2ROT - AreaX4ROT) / density);
MaxArrayY := Trunc((AreaY1ROT - AreaY3ROT) / density);
END;
IF (angle >= 180) AND (angle < 270) THEN BEGIN
MaxArrayX := Trunc((AreaX1ROT - AreaX3ROT) / density);
MaxArrayY := Trunc((AreaY4ROT - AreaY2ROT) / density);
END;
IF (angle >= 270) AND (angle <= 360) THEN BEGIN
MaxArrayX := Trunc((AreaX4ROT - AreaX2ROT) / density);
MaxArrayY := Trunc((AreaY3ROT - AreaY1ROT) / density);
END;
IF (angle >= -90) AND (angle < 0) THEN BEGIN
MaxArrayX := Trunc((AreaX4ROT - AreaX2ROT) / density);
MaxArrayY := Trunc((AreaY3ROT - AreaY1ROT) / density);
END;
IF (angle >= -180) AND (angle < -90) THEN BEGIN
MaxArrayX := Trunc((AreaX1ROT - AreaX3ROT) / density);
MaxArrayY := Trunc((AreaY4ROT - AreaY2ROT) / density);
END;
IF (angle >= -270) AND (angle < -180) THEN BEGIN
MaxArrayX := Trunc((AreaX2ROT - AreaX4ROT) / density);
MaxArrayY := Trunc((AreaY1ROT - AreaY3ROT) / density);
END;
IF (angle >= -360) AND (angle < -270) THEN BEGIN
MaxArrayX := Trunc((AreaX3ROT - AreaX1ROT) / density);
MaxArrayY := Trunc((AreaY2ROT - AreaY4ROT) / density);
END;
ALLOCATE ArrayPt[1..MaxArrayX,1..MaxArrayY];
{### FILL ARRAY WITH POINTS ###}
FOR i := 1 TO MaxArrayY DO BEGIN
PenFore(52000,39000,26000);
PenSize(70);
FillPat(0);
Smooth(2);
OpenPoly;
BeginPoly;
FOR k := 1 TO MaxArrayX DO BEGIN
{### DEFINE AREA TO BE CHECKED FOR POLYPOINTS ###}
IF (AreaX1ROT <= AreaX2ROT) THEN BEGIN
IF (AreaX1ROT <= AreaX3ROT) THEN BEGIN
IF (AreaX1ROT <= AreaX4ROT) THEN XTemp := AreaX1ROT + (k*density) - (0.5 * density);
IF (AreaX1ROT > AreaX4ROT) THEN XTemp := AreaX4ROT + (k*density) - (0.5 * density);
END;
IF (AreaX1ROT > AreaX3ROT) THEN BEGIN
IF (AreaX3ROT <= AreaX4ROT) THEN XTemp := AreaX3ROT + (k*density) - (0.5 * density);
IF (AreaX3ROT > AreaX4ROT) THEN XTemp := AreaX4ROT + (k*density) - (0.5 * density);
END;
END;
IF (AreaX1ROT > AreaX2ROT) THEN BEGIN
IF (AreaX2ROT <= AreaX3ROT) THEN BEGIN
IF (AreaX2ROT <= AreaX4ROT) THEN XTemp := AreaX2ROT + (k*density) - (0.5 * density);
IF (AreaX2ROT > AreaX4ROT) THEN XTemp := AreaX4ROT + (k*density) - (0.5 * density);
END;
IF (AreaX2ROT > AreaX3ROT) THEN BEGIN
IF (AreaX3ROT <= AreaX4ROT) THEN XTemp := AreaX3ROT + (k*density) - (0.5 * density);
IF (AreaX3ROT > AreaX4ROT) THEN XTemp := AreaX4ROT + (k*density) - (0.5 * density);
END;
END;
IF (AreaY1ROT <= AreaY2ROT) THEN BEGIN
IF (AreaY1ROT <= AreaY3ROT) THEN BEGIN
IF (AreaY1ROT <= AreaY4ROT) THEN YTemp := AreaY1ROT + (i*density) - (0.5 * density);
IF (AreaY1ROT > AreaY4ROT) THEN YTemp := AreaY4ROT + (i*density) - (0.5 * density);
END;
IF (AreaY1ROT > AreaY3ROT) THEN BEGIN
IF (AreaY3ROT <= AreaY4ROT) THEN YTemp := AreaY3ROT + (i*density) - (0.5 * density);
IF (AreaY3ROT > AreaY4ROT) THEN YTemp := AreaY4ROT + (i*density) - (0.5 * density);
END;
END;
IF (AreaY1ROT > AreaY2ROT) THEN BEGIN
IF (AreaY2ROT <= AreaY3ROT) THEN BEGIN
IF (AreaY2ROT <= AreaY4ROT) THEN YTemp := AreaY2ROT + (i*density) - (0.5 * density);
IF (AreaY2ROT > AreaY4ROT) THEN YTemp := AreaY4ROT + (i*density) - (0.5 * density);
END;
IF (AreaY2ROT > AreaY3ROT) THEN BEGIN
IF (AreaY3ROT <= AreaY4ROT) THEN YTemp := AreaY3ROT + (i*density) - (0.5 * density);
IF (AreaY3ROT > AreaY4ROT) THEN YTemp := AreaY4ROT + (i*density) - (0.5 * density);
END;
END;
{### CONSIDER DISTURBANCE POINTS ###}
IF Disturb1 = TRUE THEN BEGIN
{### DETERMINE DISTANCE TO DISTURBANCE POINT 1 ###}
dist1 := sqrt(sqr(DistPtX1ROT - XTemp) + sqr(DistPtY1ROT - YTemp));
{### SHIFT POINTS OF POLY (DEPENDING ON DISTANCE TO DISTURBANCE POINT) ###}
IF dist1 < (Effect1*Stone1Rad) THEN BEGIN
DistField1 := Deg2Rad(180 / (Effect1*Stone1Rad / dist1));
IF YTemp < DistPtY1ROT THEN YTemp1 := YTemp - (0.55*Stone1Rad * (Cos(DistField1) + 1));
IF YTemp = DistPtY1ROT THEN YTemp1 := YTemp - (0.55*Stone1Rad * (Cos(DistField1) + 1));
IF YTemp > DistPtY1ROT THEN YTemp1 := YTemp + (0.55*Stone1Rad * (Cos(DistField1) + 1));
END;
IF dist1 >= (Effect1*Stone1Rad) THEN YTemp1 := YTemp;
END;
IF Disturb1 = FALSE THEN YTemp1 := YTemp;
IF Disturb2 = TRUE THEN BEGIN
{### DETERMINE DISTANCE TO DISTURBANCE POINT 2 ###}
dist2 := sqrt(sqr(DistPtX2ROT - XTemp) + sqr(DistPtY2ROT - YTemp1));
{### SHIFT POINTS OF POLY (DEPENDING ON DISTANCE TO DISTURBANCE POINT) ###}
IF dist2 < (Effect2*Stone2Rad) THEN BEGIN
DistField2 := Deg2Rad(180 / (Effect2*Stone2Rad / dist2));
IF YTemp1 < DistPtY2ROT THEN YTemp2 := YTemp1 - (0.55*Stone2Rad * (Cos(DistField2) + 1));
IF YTemp1 = DistPtY2ROT THEN YTemp2 := YTemp1 - (0.55*Stone2Rad * (Cos(DistField2) + 1));
IF YTemp1 > DistPtY2ROT THEN YTemp2 := YTemp1 + (0.55*Stone2Rad * (Cos(DistField2) + 1));
END;
IF dist2 >= (Effect2*Stone2Rad) THEN YTemp2 := YTemp1;
END;
IF Disturb2 = FALSE THEN YTemp2 := YTemp1;
IF Disturb3 = TRUE THEN BEGIN
{### DETERMINE DISTANCE TO DISTURBANCE POINT 3 ###}
dist3 := sqrt(sqr(DistPtX3ROT - XTemp) + sqr(DistPtY3ROT - YTemp2));
{### SHIFT POINTS OF POLY (DEPENDING ON DISTANCE TO DISTURBANCE POINT) ###}
IF dist3 < (Effect3*Stone3Rad) THEN BEGIN
DistField3 := Deg2Rad(180 / (Effect3*Stone3Rad / dist3));
IF YTemp2 < DistPtY3ROT THEN YTemp3 := YTemp2 - (0.55*Stone3Rad * (Cos(DistField3) + 1));
IF YTemp2 = DistPtY3ROT THEN YTemp3 := YTemp2 - (0.55*Stone3Rad * (Cos(DistField3) + 1));
IF YTemp2 > DistPtY3ROT THEN YTemp3 := YTemp2 + (0.55*Stone3Rad * (Cos(DistField3) + 1));
END;
IF dist3 >= (Effect3*Stone3Rad) THEN YTemp3 := YTemp2;
END;
IF Disturb3 = FALSE THEN YTemp3 := YTemp2;
{### GRID OF POINTS TO CREATE "WAVEPOLYS" ###}
ArrayPt[k,i].x := XTemp + (intfer * (random-0.5) * density);
ArrayPt[k,i].y := YTemp3 + (intfer * (random-0.5) * density);
InCheck4 := PtInPoly(ArrayPt[k,i].x, ArrayPt[k,i].y, BorderPoly);
IF InCheck4 = TRUE THEN AddPoint(ArrayPt[k,i].x, ArrayPt[k,i].y);
END;
EndPoly;
ReDrawAll;
END;
{######### ROTATE WHOLE PATTERN TO ORIGINAL POSITION #########}
SelectAll;
RotatePoint(AreaX1,AreaY1,angle);
DSelectAll;
END;
Run(SandWaves);
-- NDSMartinTann - 03 Nov 2005
|