List of all Capital Cities

Sunday, July 17th, 2011

Might be usefull sometime (used for the entoforms).

Tirana, Andorra la Vella, Vienna, Minsk, Brussels, Sarajevo, Sofia, Zagreb, Nicosia, Prague, Copenhagen, London, Tallinn, Helsinki, Paris, Tbilisi, Berlin, Athens, Budapest, Reykjavik, Dublin, Rome, Pristina, Riga, Vaduz, Vilnius, Luxembourg, Skopje, Valletta, Chisinau, Monaco, Podgorica, Amsterdam, Belfast, Oslo, Warsaw, Lisbon, Bucharest, Moscow, San Marino, Edinburgh, Belgrade, Bratislava, Ljubljana, Madrid, Stockholm, Bern, Kiev, Cardiff,  Algiers, Luanda, Porto-Novo, Gaborone, Ouagadougou, Bujumbura, Yaounde, Praia, Bangu, N’Djamena, Moroni, Brazzaville, Kinshasa, Yamoussoukro, Djibouti, Cairo, Malabo, Asmara, Addis Ababa, Libreville, Banjul, Accra, Conakry, Bissau, Nairobi, Maseru, Monrovia, Tripoli, Antananarivo, Lilongwe, Bamako, Nouakchott, Port Louis, Rabat, Maputo, Windhoek, Niamey, Abuja, Kigali, Sao Tome, Dakar, Victoria, Freetown, Mogadishu, Pretoria, Khartoum, Mbabane, Dar es Salaam, Lome, Tunis, Kampala, El Aaiun, Lusaka, Harare, Kabul, Yerevan, Baku, Manama, Dhaka, Thimphu, Bandar Seri Begawan, Rangoon, Phnom Penh, Beijing, Dili, New Delhi, Jakarta, Teheran, Baghdad, Jerusalem, Tokyo, Amman, Astana, Pyongyang, Seoul, Kuwait City, Bishkek, Vientiane, Beirut, Kuala Lumpur, Male, Ulan Bator, Kathmandu, Muscat, Islamabad, Manila, Doha, Riyadh, Singapore, Colombo, Sri Jayawardenepura-Kotte, Damascus, Taipei, Dushanbe, Bangkok, Ankara, Ashgabat, Abu Dhabi, Tashkent, Hanoi, Sana,  St. John’s, Nassau, Bridgetown, Belmopan, Ottawa – Ontario, San Jose, Havana, Roseau, Santo Domingo, San Salvador, Nuuk, St. George’s, Guatemala City, Port-au-Prince, Tegucigalpa, Kingston, Mexico City, Managua, Panama City, Basseterre, Castries, Kingstown, Port-of-Spain, Washington D.C.,  Canberra, Suva, Tarawa, Majuro, Palikir, Yaren, Wellington, Koror, Port Moresby, Apia, Honiara, Nuku’alofa, Funafuti, Port Vila,  Buenos Aires, La Paz, Sucre, Brasilia, Santiago, Bogota, Quito, Georgetown, Asuncion, Lima, Paramaribo, Montevideo, Caracas

Using bezier math in Blender with python

Monday, January 31st, 2011

Ok, so once again, this is mostly here so I can remember…

For my Entoforms project I’ve been using sine waves to calculate nice “increases” and “decreases”, but… a sine wave is only so flexible. Thus I had a look at using beziers in stead. Now… I am an artist, and not a math wizz, so it was tricky to get my head around…

The concept

Because I’m just using this bit of math to calulate how much I want to transform stuff, I’m only doing it in 2D. And to keep it simple only with curves with a single segment (though you can combine multiple curves). Below here are a few nice ones.

Now in my case I only care about the “inside” of the curve… so we’re ignoring the black (unselected) handles. This results in each curve being defined by 4 points… 2 nodes (where the curve starts and ends) and 2 handles (that define the shape of the curve). So we have p0 (the first node), p1 (the handle for the first node), p2 (the handle for the second node), p3 (the second node).

The math

I was lucky enough to find some very basic math for this on the net… I really don’t know much about what it actually does, but it works great! So here’s a simple script that places empties along a bezier curve.

  1. import bpy, math, mathutils
  2.  
  3. # Kappa is the position of the handle on a circular curve
  4. kappa = ((math.sqrt(2)-1)/3)*4
  5.  
  6. # A series of nice bezier curves
  7. beziers = {
  8.         'linear': {
  9.                 'p0': mathutils.Vector((0.0,0.0)),
  10.                 'p1':mathutils.Vector((0.5,0.5)),
  11.                 'p2':mathutils.Vector((0.5,0.5)),
  12.                 'p3':mathutils.Vector((1.0,1.0))
  13.                 },
  14.         'increasing': {
  15.                 'p0': mathutils.Vector((0.0,0.0)),
  16.                 'p1':mathutils.Vector((kappa,0.0)),
  17.                 'p2':mathutils.Vector((1.0,(1.0-kappa))),
  18.                 'p3':mathutils.Vector((1.0,1.0))
  19.                 },
  20.         'decreasing': {
  21.                 'p0': mathutils.Vector((0.0,0.0)),
  22.                 'p1':mathutils.Vector((0.0,kappa)),
  23.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  24.                 'p3':mathutils.Vector((1.0,1.0))
  25.                 },
  26.         'swoop': {
  27.                 'p0': mathutils.Vector((0.0,0.0)),
  28.                 'p1':mathutils.Vector((0.5,0.0)),
  29.                 'p2':mathutils.Vector((0.5,1.0)),
  30.                 'p3':mathutils.Vector((1.0,1.0))
  31.                 },
  32.         }
  33.  
  34. # Find a point along a bezier curve
  35. def findBezierPoint(r, curve):
  36.         c = 3 * (curve['p1'] - curve['p0'])
  37.         b = 3 * (curve['p2'] - curve['p1']) - c
  38.         a = curve['p3'] - curve['p0'] - c - b
  39.  
  40.         r2 = r * r
  41.         r3 = r2 * r
  42.  
  43.         return a * r3 + b * r2 + c * r + curve['p0']
  44.  
  45. # Pick a bezier curve
  46. bezier = beziers['increasing']
  47.  
  48. # Loop through and find points along a bezier curve
  49. for i in range(11):
  50.  
  51.         b = findBezierPoint((i*0.1),bezier)
  52.  
  53.         print((i+1),b)
  54.  
  55.         b*=10
  56.  
  57.         bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=(b[0], 0, b[1]), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

Display clean python code for copying

import bpy, math, mathutils

# Kappa is the position of the handle on a circular curve
kappa = ((math.sqrt(2)-1)/3)*4

# A series of nice bezier curves
beziers = {
	'linear': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.5,0.5)),
		'p2':mathutils.Vector((0.5,0.5)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'increasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector((1.0,(1.0-kappa))),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'decreasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.0,kappa)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'swoop': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.5,0.0)),
		'p2':mathutils.Vector((0.5,1.0)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	}

# Find a point along a bezier curve
def findBezierPoint(r, curve):
	c = 3 * (curve['p1'] - curve['p0'])
	b = 3 * (curve['p2'] - curve['p1']) - c
	a = curve['p3'] - curve['p0'] - c - b

	r2 = r * r
	r3 = r2 * r

	return a * r3 + b * r2 + c * r + curve['p0']

# Pick a bezier curve
bezier = beziers['increasing']

# Loop through and find points along a bezier curve
for i in range(11):

	b = findBezierPoint((i*0.1),bezier)

	print((i+1),b)

	b*=10

	bpy.ops.object.add(type='EMPTY', view_align=False, enter_editmode=False, location=(b[0], 0, b[1]), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

The use

Now this gives us a nice series of numbers from 0.0 to 1.0. These can be used to calculate how strongly we want to affect something… it’s basically a falloff curve. The trick is not to use these as actual transformation values, but as a reference for how much of the “end” result should be reached. So if you’re translating something 20 units, and the value retrieved is 0.4… the selection should be translated 20 * 0.4 units at this point in time.

Here’s a slightly usefull example

  1. import bpy, math, mathutils
  2.  
  3. # Kappa is the position of the handle on a circular curve
  4. kappa = ((math.sqrt(2)-1)/3)*4
  5.  
  6. # A series of nice 2D bezier curves
  7. beziers = {
  8.         'linear': {
  9.                 'p0': mathutils.Vector((0.0,0.0)),
  10.                 'p1':mathutils.Vector((0.5,0.5)),
  11.                 'p2':mathutils.Vector((0.5,0.5)),
  12.                 'p3':mathutils.Vector((1.0,1.0))
  13.                 },
  14.         'increasing': {
  15.                 'p0': mathutils.Vector((0.0,0.0)),
  16.                 'p1':mathutils.Vector((kappa,0.0)),
  17.                 'p2':mathutils.Vector((1.0,(1.0-kappa))),
  18.                 'p3':mathutils.Vector((1.0,1.0))
  19.                 },
  20.         'decreasing': {
  21.                 'p0': mathutils.Vector((0.0,0.0)),
  22.                 'p1':mathutils.Vector((0.0,kappa)),
  23.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  24.                 'p3':mathutils.Vector((1.0,1.0))
  25.                 },
  26.         'swoop': {
  27.                 'p0': mathutils.Vector((0.0,0.0)),
  28.                 'p1':mathutils.Vector((kappa,0.0)),
  29.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  30.                 'p3':mathutils.Vector((1.0,1.0))
  31.                 },
  32.         }
  33.  
  34. # Find a point along a bezier curve
  35. def findBezierPoint(r, curve):
  36.         c = 3 * (curve['p1'] - curve['p0'])
  37.         b = 3 * (curve['p2'] - curve['p1']) - c
  38.         a = curve['p3'] - curve['p0'] - c - b
  39.  
  40.         r2 = r * r
  41.         r3 = r2 * r
  42.  
  43.         return a * r3 + b * r2 + c * r + curve['p0']
  44.  
  45. # Now lets do something usefull!
  46. # Lets say we want to scale something * 5.0 in 10 steps
  47.  
  48. # So we add a cube to do this to
  49. bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
  50.  
  51. # Pick a bezier curve
  52. bezier = beziers['increasing']
  53.  
  54. # The number of steps we want to do this in
  55. iterations = 10
  56.  
  57. # The stepsize is how far along the curve we move in each step
  58. # This starts at 0.0 and ends at 1.0
  59. stepSize = (1.0 / iterations)
  60.  
  61. # The size we start with is always 1 because we do it relative
  62. startSize = 1.0
  63.  
  64. # The size at the end of the process should be the start multiplied by this
  65. scaleUp = 5.0
  66.  
  67. # We get the difference in scale so we can figure out each step
  68. scaleDif = scaleUp - startSize
  69.  
  70. # This is here to see if the progression is correct
  71. checkSize = startSize
  72.  
  73. # Lets do 10 steps
  74. for i in range(10):
  75.  
  76.         # Before we do anything we find out where we should be at this point in time
  77.         previousStep = i
  78.  
  79.         # Before we do anything we find out where we should be at this point in time
  80.         previousPoint = stepSize * i
  81.  
  82.         # Find the point on the curve for the previous iteration in the loop
  83.         b = findBezierPoint(previousPoint, bezier)
  84.  
  85.         # This should tell us what the current size of the object is
  86.         currentSize = (scaleDif * b[1]) + startSize
  87.  
  88.         # Now lets find out how much bigger we need to make it
  89.         # We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
  90.         step = (i+1)
  91.  
  92.         # The point along the curve is always a nr between 0.0 and 1.0
  93.         # So we divide 1 by the number of iterations to find the stepsize
  94.         curvePoint =  stepSize * step
  95.  
  96.         # Find the point on the curve for this iteration in the loop
  97.         b = findBezierPoint(curvePoint, bezier)
  98.  
  99.         # This should be the size we want to achieve
  100.         newSize = (scaleDif * b[1]) + startSize
  101.  
  102.         scaleFactor = newSize / currentSize
  103.  
  104.         checkSize *= scaleFactor
  105.  
  106.         # Lets print out some values to check
  107.         print('step',step)
  108.         print('  currentSize',currentSize)
  109.         print('  newSize', newSize)
  110.         print('  scaleFactor', scaleFactor)
  111.         print('  checkSize',checkSize)
  112.  
  113.         # lets add some meshes so we can see the effect
  114.         b*=20
  115.         bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
  116.         bpy.context.active_object.location = (b[0],0.0,b[1])
  117.         bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

Display clean python code for copying

import bpy, math, mathutils

# Kappa is the position of the handle on a circular curve
kappa = ((math.sqrt(2)-1)/3)*4

# A series of nice 2D bezier curves
beziers = {
	'linear': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.5,0.5)),
		'p2':mathutils.Vector((0.5,0.5)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'increasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector((1.0,(1.0-kappa))),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'decreasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.0,kappa)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	'swoop': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0))
		},
	}

# Find a point along a bezier curve
def findBezierPoint(r, curve):
	c = 3 * (curve['p1'] - curve['p0'])
	b = 3 * (curve['p2'] - curve['p1']) - c
	a = curve['p3'] - curve['p0'] - c - b

	r2 = r * r
	r3 = r2 * r

	return a * r3 + b * r2 + c * r + curve['p0']

# Now lets do something usefull!
# Lets say we want to scale something * 5.0 in 10 steps

# So we add a cube to do this to
bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

# Pick a bezier curve
bezier = beziers['increasing']

# The number of steps we want to do this in
iterations = 10

# The stepsize is how far along the curve we move in each step
# This starts at 0.0 and ends at 1.0
stepSize = (1.0 / iterations)

# The size we start with is always 1 because we do it relative
startSize = 1.0 

# The size at the end of the process should be the start multiplied by this
scaleUp = 5.0

# We get the difference in scale so we can figure out each step
scaleDif = scaleUp - startSize

# This is here to see if the progression is correct
checkSize = startSize

# Lets do 10 steps
for i in range(10):

	# Before we do anything we find out where we should be at this point in time
	previousStep = i

	# Before we do anything we find out where we should be at this point in time
	previousPoint = stepSize * i

	# Find the point on the curve for the previous iteration in the loop
	b = findBezierPoint(previousPoint, bezier)

	# This should tell us what the current size of the object is
	currentSize = (scaleDif * b[1]) + startSize

	# Now lets find out how much bigger we need to make it
	# We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
	step = (i+1)

	# The point along the curve is always a nr between 0.0 and 1.0
	# So we divide 1 by the number of iterations to find the stepsize
	curvePoint =  stepSize * step

	# Find the point on the curve for this iteration in the loop
	b = findBezierPoint(curvePoint, bezier)

	# This should be the size we want to achieve
	newSize = (scaleDif * b[1]) + startSize

	scaleFactor = newSize / currentSize

	checkSize *= scaleFactor

	# Lets print out some values to check
	print('step',step)
	print('  currentSize',currentSize)
	print('  newSize', newSize)
	print('  scaleFactor', scaleFactor)
	print('  checkSize',checkSize)

	# lets add some meshes so we can see the effect
	b*=20
	bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
	bpy.context.active_object.location = (b[0],0.0,b[1])
	bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

And another version that allows for stringing together multiple curves

  1. import bpy, math, mathutils
  2.  
  3. print('-- starting --')
  4.  
  5. # Kappa is the position of the handle on a circular curve
  6. kappa = ((math.sqrt(2)-1)/3)*4
  7.  
  8. # A series of nice 2D bezier curves
  9. beziers = {
  10.         'linear': {
  11.                 'p0': mathutils.Vector((0.0,0.0)),
  12.                 'p1':mathutils.Vector((0.5,0.5)),
  13.                 'p2':mathutils.Vector((0.5,0.5)),
  14.                 'p3':mathutils.Vector((1.0,1.0)),
  15.                 },
  16.         'increasing': {
  17.                 'p0': mathutils.Vector((0.0,0.0)),
  18.                 'p1':mathutils.Vector((kappa,0.0)),
  19.                 'p2':mathutils.Vector((1.0,(1.0-kappa))),
  20.                 'p3':mathutils.Vector((1.0,1.0)),
  21.                 },
  22.         'decreasing': {
  23.                 'p0': mathutils.Vector((0.0,0.0)),
  24.                 'p1':mathutils.Vector((0.0,kappa)),
  25.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  26.                 'p3':mathutils.Vector((1.0,1.0)),
  27.                 },
  28.         'swoosh': {
  29.                 'p0': mathutils.Vector((0.0,0.0)),
  30.                 'p1':mathutils.Vector((kappa,0.0)),
  31.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  32.                 'p3':mathutils.Vector((1.0,1.0)),
  33.                 },
  34.         }
  35.  
  36. # Find a point along a bezier curve
  37. def findBezierPoint(r, curve):
  38.         c = 3 * (curve['p1'] - curve['p0'])
  39.         b = 3 * (curve['p2'] - curve['p1']) - c
  40.         a = curve['p3'] - curve['p0'] - c - b
  41.  
  42.         r2 = r * r
  43.         r3 = r2 * r
  44.  
  45.         return a * r3 + b * r2 + c * r + curve['p0']
  46.  
  47. # Lets make a curve go from 1.0 to 0.0
  48. def invertCurve(curve):
  49.         bezier = {
  50.                 'p0': mathutils.Vector(((1.0-curve['p3'][0]),curve['p3'][1])),
  51.                 'p1':mathutils.Vector(((1.0-curve['p2'][0]),curve['p2'][1])),
  52.                 'p2':mathutils.Vector(((1.0-curve['p1'][0]),curve['p1'][1])),
  53.                 'p3': mathutils.Vector(((1.0-curve['p0'][0]),curve['p0'][1])),
  54.                 }
  55.         return bezier
  56.  
  57. # Make the intensity of a curve bigger or smaller
  58. # Intensity has to be between 0.0 and 2.0 (1.0 is default)
  59. def intensifyCurve(curve, intensity=1.0):
  60.  
  61.         bezier = {
  62.                 'p0': curve['p0'],
  63.                 'p1':curve['p1'],
  64.                 'p2':curve['p2'],
  65.                 'p3': curve['p3'],
  66.                 }
  67.  
  68.         if intensity > 1.0:
  69.                 if bezier['p1'][0]:
  70.                         dif = 1.0 - bezier['p1'][0]
  71.                         dif *= (intensity - 1.0)
  72.                         bezier['p1'][0] += dif
  73.  
  74.                 if bezier['p1'][1]:
  75.                         dif = 1.0 - bezier['p1'][1]
  76.                         dif *= (intensity - 1.0)
  77.                         bezier['p1'][1] += dif
  78.  
  79.                 if bezier['p2'][0] != 1.0:
  80.                         dif = bezier['p2'][0]
  81.                         dif *= (intensity - 1.0)
  82.                         bezier['p2'][0] -= dif
  83.  
  84.                 if bezier['p2'][1] != 1.0:
  85.                         dif = bezier['p1'][1]
  86.                         dif *= (intensity - 1.0)
  87.                         bezier['p1'][1] -= dif
  88.  
  89.         elif intensity < 1.0:
  90.                 if bezier['p1'][0]:
  91.                         bezier['p1'][0] *= intensity
  92.  
  93.                 if bezier['p1'][1]:
  94.                         bezier['p1'][1] *= intensity
  95.  
  96.                 if bezier['p2'][0] != 1.0:
  97.                         dif = 1.0 - bezier['p2'][0]
  98.                         dif *= intensity
  99.                         bezier['p2'][0] += dif
  100.  
  101.                 if bezier['p2'][1] != 1.0:
  102.                         dif = 1.0 - bezier['p2'][1]
  103.                         dif *= intensity
  104.                         bezier['p2'][1] += dif
  105.  
  106.         return bezier
  107.  
  108. # Now lets do something usefull!
  109. # Lets say we want to scale something * 5.0 in 10 steps
  110.  
  111. # So we add a cube to do this to
  112. bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
  113.  
  114. # So now lets do multiple bezier curves
  115. curves = [beziers['decreasing'],beziers['decreasing']]
  116. intensities = [1.0,1.0]
  117.  
  118. # The number of steps we want to do this in
  119. iterations = 10
  120.  
  121. # The size we start with is always 1 because we do it relative
  122. startSize = 1.0
  123.  
  124. # The size at the end of the process should be the start multiplied by this
  125. scaleUp = 5.0
  126.  
  127. # We get the difference in scale so we can figure out each step
  128. scaleDif = scaleUp - startSize
  129.  
  130. # This is here to see if the progression is correct
  131. checkSize = startSize
  132.  
  133. # The number of iterations per curve
  134. split = iterations / len(curves)
  135. stepSize = (1.0/iterations) * len(curves)
  136.  
  137. # Lets do 10 steps
  138. for i in range(iterations):
  139.  
  140.         # Before we do anything we find out where we should be at this point in time
  141.         step = i
  142.  
  143.         # Figure out what curve we need to use
  144.         curveId = math.floor(step/split)
  145.         curve = curves[curveId]
  146.  
  147.         # Set the intensity for a curve
  148.         curve = intensifyCurve(curve, intensities[curveId])
  149.  
  150.         # Make sure each curve is interpreted start to finish
  151.         step -= (curveId * split)
  152.  
  153.         # Find out if we're even or odd!
  154.         # To make transistions nice we invert the even curves
  155.         odd = curveId % 2
  156.         if odd:
  157.                 curve = invertCurve(curve)
  158.  
  159.         # Before we do anything we find out where we should be at this point in time
  160.         curvePoint = stepSize * step
  161.  
  162.         # Find the point on the curve for the previous iteration in the loop
  163.         currentPoint = findBezierPoint(curvePoint, curve)
  164.  
  165.         # This should tell us what the current size of the object is
  166.         currentOffset = (scaleDif * currentPoint[1]) + startSize
  167.  
  168.         # Now lets find out how much bigger we need to make it
  169.         # We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
  170.         step += 1
  171.  
  172.         # The point along the curve is always a nr between 0.0 and 1.0
  173.         # So we divide 1 by the number of iterations to find the stepsize
  174.         curvePoint =  stepSize * step
  175.  
  176.         # Find the point on the curve for this iteration in the loop
  177.         newPoint = findBezierPoint(curvePoint, curve)
  178.  
  179.         # This should be the size we want to achieve
  180.         newOffset = (scaleDif * newPoint[1]) + startSize
  181.  
  182.         scaleFactor = newOffset / currentOffset
  183.  
  184.         checkSize *= scaleFactor
  185.  
  186.         # Lets print out some values to check
  187.         print('step',step)
  188.         print('  stepSize',stepSize)
  189.         print('  curve',curveId)
  190.         print('  currentPoint', currentPoint[1])
  191.         print('  newPoint', newPoint[1])
  192.         print('  currentOffset',currentOffset)
  193.         print('  newOffset', newOffset)
  194.         print('  scaleFactor', scaleFactor)
  195.         print('  checkSize',checkSize)
  196.  
  197.         # lets add some meshes so we can see the effect
  198.         bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
  199.         bpy.context.active_object.location = (((newPoint[0]*iterations*2)+(curveId*iterations*2)),0.0,(newPoint[1]*iterations*2))
  200.         bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

Display clean python code for copying

import bpy, math, mathutils

print('-- starting --')

# Kappa is the position of the handle on a circular curve
kappa = ((math.sqrt(2)-1)/3)*4

# A series of nice 2D bezier curves
beziers = {
	'linear': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.5,0.5)),
		'p2':mathutils.Vector((0.5,0.5)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'increasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector((1.0,(1.0-kappa))),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'decreasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.0,kappa)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'swoosh': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	}

# Find a point along a bezier curve
def findBezierPoint(r, curve):
	c = 3 * (curve['p1'] - curve['p0'])
	b = 3 * (curve['p2'] - curve['p1']) - c
	a = curve['p3'] - curve['p0'] - c - b

	r2 = r * r
	r3 = r2 * r

	return a * r3 + b * r2 + c * r + curve['p0']

# Lets make a curve go from 1.0 to 0.0
def invertCurve(curve):
	bezier = {
		'p0': mathutils.Vector(((1.0-curve['p3'][0]),curve['p3'][1])),
		'p1':mathutils.Vector(((1.0-curve['p2'][0]),curve['p2'][1])),
		'p2':mathutils.Vector(((1.0-curve['p1'][0]),curve['p1'][1])),
		'p3': mathutils.Vector(((1.0-curve['p0'][0]),curve['p0'][1])),
		}
	return bezier

# Make the intensity of a curve bigger or smaller
# Intensity has to be between 0.0 and 2.0 (1.0 is default)
def intensifyCurve(curve, intensity=1.0):

	bezier = {
		'p0': curve['p0'],
		'p1':curve['p1'],
		'p2':curve['p2'],
		'p3': curve['p3'],
		}

	if intensity > 1.0:
		if bezier['p1'][0]:
			dif = 1.0 - bezier['p1'][0]
			dif *= (intensity - 1.0)
			bezier['p1'][0] += dif

		if bezier['p1'][1]:
			dif = 1.0 - bezier['p1'][1]
			dif *= (intensity - 1.0)
			bezier['p1'][1] += dif

		if bezier['p2'][0] != 1.0:
			dif = bezier['p2'][0]
			dif *= (intensity - 1.0)
			bezier['p2'][0] -= dif

		if bezier['p2'][1] != 1.0:
			dif = bezier['p1'][1]
			dif *= (intensity - 1.0)
			bezier['p1'][1] -= dif

	elif intensity < 1.0:
		if bezier['p1'][0]:
			bezier['p1'][0] *= intensity

		if bezier['p1'][1]:
			bezier['p1'][1] *= intensity

		if bezier['p2'][0] != 1.0:
			dif = 1.0 - bezier['p2'][0]
			dif *= intensity
			bezier['p2'][0] += dif

		if bezier['p2'][1] != 1.0:
			dif = 1.0 - bezier['p2'][1]
			dif *= intensity
			bezier['p2'][1] += dif

	return bezier

# Now lets do something usefull!
# Lets say we want to scale something * 5.0 in 10 steps

# So we add a cube to do this to
bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

# So now lets do multiple bezier curves
curves = [beziers['decreasing'],beziers['decreasing']]
intensities = [1.0,1.0]

# The number of steps we want to do this in
iterations = 10

# The size we start with is always 1 because we do it relative
startSize = 1.0 

# The size at the end of the process should be the start multiplied by this
scaleUp = 5.0

# We get the difference in scale so we can figure out each step
scaleDif = scaleUp - startSize

# This is here to see if the progression is correct
checkSize = startSize

# The number of iterations per curve
split = iterations / len(curves)
stepSize = (1.0/iterations) * len(curves)

# Lets do 10 steps
for i in range(iterations):

	# Before we do anything we find out where we should be at this point in time
	step = i

	# Figure out what curve we need to use
	curveId = math.floor(step/split)
	curve = curves[curveId]

	# Set the intensity for a curve
	curve = intensifyCurve(curve, intensities[curveId])

	# Make sure each curve is interpreted start to finish
	step -= (curveId * split)

	# Find out if we're even or odd!
	# To make transistions nice we invert the even curves
	odd = curveId % 2
	if odd:
		curve = invertCurve(curve)

	# Before we do anything we find out where we should be at this point in time
	curvePoint = stepSize * step

	# Find the point on the curve for the previous iteration in the loop
	currentPoint = findBezierPoint(curvePoint, curve)

	# This should tell us what the current size of the object is
	currentOffset = (scaleDif * currentPoint[1]) + startSize

	# Now lets find out how much bigger we need to make it
	# We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
	step += 1

	# The point along the curve is always a nr between 0.0 and 1.0
	# So we divide 1 by the number of iterations to find the stepsize
	curvePoint =  stepSize * step

	# Find the point on the curve for this iteration in the loop
	newPoint = findBezierPoint(curvePoint, curve)

	# This should be the size we want to achieve
	newOffset = (scaleDif * newPoint[1]) + startSize

	scaleFactor = newOffset / currentOffset

	checkSize *= scaleFactor

	# Lets print out some values to check
	print('step',step)
	print('  stepSize',stepSize)
	print('  curve',curveId)
	print('  currentPoint', currentPoint[1])
	print('  newPoint', newPoint[1])
	print('  currentOffset',currentOffset)
	print('  newOffset', newOffset)
	print('  scaleFactor', scaleFactor)
	print('  checkSize',checkSize)

	# lets add some meshes so we can see the effect
	bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
	bpy.context.active_object.location = (((newPoint[0]*iterations*2)+(curveId*iterations*2)),0.0,(newPoint[1]*iterations*2))
	bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

Another addition, having the 3rd and 4th curve go negative

  1. import bpy, math, mathutils
  2.  
  3. print('-- starting --')
  4.  
  5. # Kappa is the position of the handle on a circular curve
  6. kappa = ((math.sqrt(2)-1)/3)*4
  7.  
  8. # A series of nice 2D bezier curves
  9. beziers = {
  10.         'linear': {
  11.                 'p0': mathutils.Vector((0.0,0.0)),
  12.                 'p1':mathutils.Vector((0.5,0.5)),
  13.                 'p2':mathutils.Vector((0.5,0.5)),
  14.                 'p3':mathutils.Vector((1.0,1.0)),
  15.                 },
  16.         'increasing': {
  17.                 'p0': mathutils.Vector((0.0,0.0)),
  18.                 'p1':mathutils.Vector((kappa,0.0)),
  19.                 'p2':mathutils.Vector((1.0,(1.0-kappa))),
  20.                 'p3':mathutils.Vector((1.0,1.0)),
  21.                 },
  22.         'decreasing': {
  23.                 'p0': mathutils.Vector((0.0,0.0)),
  24.                 'p1':mathutils.Vector((0.0,kappa)),
  25.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  26.                 'p3':mathutils.Vector((1.0,1.0)),
  27.                 },
  28.         'swoosh': {
  29.                 'p0': mathutils.Vector((0.0,0.0)),
  30.                 'p1':mathutils.Vector((kappa,0.0)),
  31.                 'p2':mathutils.Vector(((1.0-kappa),1.0)),
  32.                 'p3':mathutils.Vector((1.0,1.0)),
  33.                 },
  34.         }
  35.  
  36. # Find a point along a bezier curve
  37. def findBezierPoint(r, curve):
  38.         c = 3 * (curve['p1'] - curve['p0'])
  39.         b = 3 * (curve['p2'] - curve['p1']) - c
  40.         a = curve['p3'] - curve['p0'] - c - b
  41.  
  42.         r2 = r * r
  43.         r3 = r2 * r
  44.  
  45.         return a * r3 + b * r2 + c * r + curve['p0']
  46.  
  47. # Lets make a curve go from 1.0 to 0.0
  48. def reverseCurve(curve):
  49.         bezier = {
  50.                 'p0': mathutils.Vector(((1.0-curve['p3'][0]),curve['p3'][1])),
  51.                 'p1': mathutils.Vector(((1.0-curve['p2'][0]),curve['p2'][1])),
  52.                 'p2': mathutils.Vector(((1.0-curve['p1'][0]),curve['p1'][1])),
  53.                 'p3': mathutils.Vector(((1.0-curve['p0'][0]),curve['p0'][1])),
  54.                 }
  55.         return bezier
  56.  
  57. # Negate a curve
  58. def negateCurve(curve):
  59.         bezier = {
  60.                 'p0': mathutils.Vector((curve['p0'][0],-curve['p0'][1])),
  61.                 'p1': mathutils.Vector((curve['p1'][0],-curve['p1'][1])),
  62.                 'p2': mathutils.Vector((curve['p2'][0],-curve['p2'][1])),
  63.                 'p3': mathutils.Vector((curve['p3'][0],-curve['p3'][1])),
  64.                 }
  65.         return bezier
  66.  
  67. # Make the intensity of a curve bigger or smaller
  68. # Intensity has to be between 0.0 and 2.0 (1.0 is default)
  69. def intensifyCurve(curve, intensity=1.0):
  70.  
  71.         bezier = {
  72.                 'p0': curve['p0'],
  73.                 'p1': curve['p1'],
  74.                 'p2': curve['p2'],
  75.                 'p3': curve['p3'],
  76.                 }
  77.  
  78.         if intensity > 1.0:
  79.                 if bezier['p1'][0]:
  80.                         dif = 1.0 - bezier['p1'][0]
  81.                         dif *= (intensity - 1.0)
  82.                         bezier['p1'][0] += dif
  83.  
  84.                 if bezier['p1'][1]:
  85.                         dif = 1.0 - bezier['p1'][1]
  86.                         dif *= (intensity - 1.0)
  87.                         bezier['p1'][1] += dif
  88.  
  89.                 if bezier['p2'][0] != 1.0:
  90.                         dif = bezier['p2'][0]
  91.                         dif *= (intensity - 1.0)
  92.                         bezier['p2'][0] -= dif
  93.  
  94.                 if bezier['p2'][1] != 1.0:
  95.                         dif = bezier['p1'][1]
  96.                         dif *= (intensity - 1.0)
  97.                         bezier['p1'][1] -= dif
  98.  
  99.         elif intensity < 1.0:
  100.                 if bezier['p1'][0]:
  101.                         bezier['p1'][0] *= intensity
  102.  
  103.                 if bezier['p1'][1]:
  104.                         bezier['p1'][1] *= intensity
  105.  
  106.                 if bezier['p2'][0] != 1.0:
  107.                         dif = 1.0 - bezier['p2'][0]
  108.                         dif *= intensity
  109.                         bezier['p2'][0] += dif
  110.  
  111.                 if bezier['p2'][1] != 1.0:
  112.                         dif = 1.0 - bezier['p2'][1]
  113.                         dif *= intensity
  114.                         bezier['p2'][1] += dif
  115.  
  116.         return bezier
  117.  
  118. # Now lets do something usefull!
  119. # Lets say we want to scale something * 5.0 in 10 steps
  120.  
  121. # So we add a cube to do this to
  122. bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
  123.  
  124. # So now lets do multiple bezier curves
  125. curves = [beziers['swoosh'],beziers['decreasing'],beziers['increasing'],beziers['increasing']]
  126. intensities = [1.0,1.0,1.0,1.0]
  127.  
  128. # The number of steps we want to do this in
  129. iterations = 40
  130.  
  131. # The size we start with is always 1 because we do it relative
  132. startSize = 1.0
  133.  
  134. # The size at the end of the process should be the start multiplied by this
  135. scaleUp = 5.0
  136.  
  137. # We get the difference in scale so we can figure out each step
  138. scaleDif = scaleUp - startSize
  139.  
  140. # This is here to see if the progression is correct
  141. checkSize = startSize
  142.  
  143. # The number of iterations per curve
  144. split = iterations / len(curves)
  145. stepSize = (1.0/iterations) * len(curves)
  146.  
  147. # Lets do 10 steps
  148. for i in range(iterations):
  149.  
  150.         # Before we do anything we find out where we should be at this point in time
  151.         step = i
  152.  
  153.         # Figure out what curve we need to use
  154.         curveId = math.floor(step/split)
  155.         curve = curves[curveId]
  156.  
  157.         # Set the intensity for a curve
  158.         curve = intensifyCurve(curve, intensities[curveId])
  159.  
  160.         # Make sure each curve is interpreted start to finish
  161.         step -= (curveId * split)
  162.  
  163.         # The current curve number for reversing and inversing should be 1-2-3-4
  164.         # 1 is regular
  165.         curveNr = (curveId +1) - (curveId//4)
  166.  
  167.         # The second and third curves are reversed (the third makes things smaller)
  168.         if curveNr is 2 or curveNr is 3:
  169.                 curve = reverseCurve(curve)
  170.  
  171.         # Before we do anything we find out where we should be at this point in time
  172.         curvePoint = stepSize * step
  173.  
  174.         # Find the point on the curve for the previous iteration in the loop
  175.         currentPoint = findBezierPoint(curvePoint, curve)
  176.  
  177.         # This should tell us what the current size of the object is
  178.         currentOffset = (scaleDif * currentPoint[1]) + startSize
  179.  
  180.         # Now lets find out how much bigger we need to make it
  181.         # We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
  182.         step += 1
  183.  
  184.         # The point along the curve is always a nr between 0.0 and 1.0
  185.         # So we divide 1 by the number of iterations to find the stepsize
  186.         curvePoint =  stepSize * step
  187.  
  188.         # Find the point on the curve for this iteration in the loop
  189.         newPoint = findBezierPoint(curvePoint, curve)
  190.  
  191.         # This should be the size we want to achieve
  192.         newOffset = (scaleDif * newPoint[1]) + startSize
  193.  
  194.         scaleFactor = newOffset / currentOffset
  195.  
  196.         checkSize *= scaleFactor
  197.  
  198.         # Lets print out some values to check
  199.         print('')
  200.         print((i+1),step,'curve',curveNr)
  201.         #print('  stepSize',stepSize)
  202.         print('  currentPoint', round(currentPoint[1],5),'newPoint',round(newPoint[1]))
  203.         #print('  currentOffset',currentOffset)
  204.         #print('  newOffset', newOffset)
  205.         print('  scaleFactor', scaleFactor)
  206.         print('  checkSize',checkSize)
  207.  
  208.         # lets add some meshes so we can see the effect
  209.         bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})
  210.  
  211.         xPos = ((newPoint[0]*iterations*2)+(curveId*iterations*2))
  212.         zPos = (newPoint[1]*iterations*2)
  213.  
  214.         if curveNr == 3 or curveNr == 4:
  215.                 zPos -= iterations*2
  216.  
  217.         bpy.context.active_object.location = (xPos,0.0,zPos)
  218.         bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

Display clean python code for copying

import bpy, math, mathutils

print('-- starting --')

# Kappa is the position of the handle on a circular curve
kappa = ((math.sqrt(2)-1)/3)*4

# A series of nice 2D bezier curves
beziers = {
	'linear': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.5,0.5)),
		'p2':mathutils.Vector((0.5,0.5)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'increasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector((1.0,(1.0-kappa))),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'decreasing': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((0.0,kappa)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	'swoosh': {
		'p0': mathutils.Vector((0.0,0.0)),
		'p1':mathutils.Vector((kappa,0.0)),
		'p2':mathutils.Vector(((1.0-kappa),1.0)),
		'p3':mathutils.Vector((1.0,1.0)),
		},
	}

# Find a point along a bezier curve
def findBezierPoint(r, curve):
	c = 3 * (curve['p1'] - curve['p0'])
	b = 3 * (curve['p2'] - curve['p1']) - c
	a = curve['p3'] - curve['p0'] - c - b

	r2 = r * r
	r3 = r2 * r

	return a * r3 + b * r2 + c * r + curve['p0']

# Lets make a curve go from 1.0 to 0.0
def reverseCurve(curve):
	bezier = {
		'p0': mathutils.Vector(((1.0-curve['p3'][0]),curve['p3'][1])),
		'p1': mathutils.Vector(((1.0-curve['p2'][0]),curve['p2'][1])),
		'p2': mathutils.Vector(((1.0-curve['p1'][0]),curve['p1'][1])),
		'p3': mathutils.Vector(((1.0-curve['p0'][0]),curve['p0'][1])),
		}
	return bezier

# Negate a curve
def negateCurve(curve):
	bezier = {
		'p0': mathutils.Vector((curve['p0'][0],-curve['p0'][1])),
		'p1': mathutils.Vector((curve['p1'][0],-curve['p1'][1])),
		'p2': mathutils.Vector((curve['p2'][0],-curve['p2'][1])),
		'p3': mathutils.Vector((curve['p3'][0],-curve['p3'][1])),
		}
	return bezier

# Make the intensity of a curve bigger or smaller
# Intensity has to be between 0.0 and 2.0 (1.0 is default)
def intensifyCurve(curve, intensity=1.0):

	bezier = {
		'p0': curve['p0'],
		'p1': curve['p1'],
		'p2': curve['p2'],
		'p3': curve['p3'],
		}

	if intensity > 1.0:
		if bezier['p1'][0]:
			dif = 1.0 - bezier['p1'][0]
			dif *= (intensity - 1.0)
			bezier['p1'][0] += dif

		if bezier['p1'][1]:
			dif = 1.0 - bezier['p1'][1]
			dif *= (intensity - 1.0)
			bezier['p1'][1] += dif

		if bezier['p2'][0] != 1.0:
			dif = bezier['p2'][0]
			dif *= (intensity - 1.0)
			bezier['p2'][0] -= dif

		if bezier['p2'][1] != 1.0:
			dif = bezier['p1'][1]
			dif *= (intensity - 1.0)
			bezier['p1'][1] -= dif

	elif intensity < 1.0:
		if bezier['p1'][0]:
			bezier['p1'][0] *= intensity

		if bezier['p1'][1]:
			bezier['p1'][1] *= intensity

		if bezier['p2'][0] != 1.0:
			dif = 1.0 - bezier['p2'][0]
			dif *= intensity
			bezier['p2'][0] += dif

		if bezier['p2'][1] != 1.0:
			dif = 1.0 - bezier['p2'][1]
			dif *= intensity
			bezier['p2'][1] += dif

	return bezier

# Now lets do something usefull!
# Lets say we want to scale something * 5.0 in 10 steps

# So we add a cube to do this to
bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(0.0, 0.0, 0.0), rotation=(0, 0, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

# So now lets do multiple bezier curves
curves = [beziers['swoosh'],beziers['decreasing'],beziers['increasing'],beziers['increasing']]
intensities = [1.0,1.0,1.0,1.0]

# The number of steps we want to do this in
iterations = 40

# The size we start with is always 1 because we do it relative
startSize = 1.0 

# The size at the end of the process should be the start multiplied by this
scaleUp = 5.0

# We get the difference in scale so we can figure out each step
scaleDif = scaleUp - startSize

# This is here to see if the progression is correct
checkSize = startSize

# The number of iterations per curve
split = iterations / len(curves)
stepSize = (1.0/iterations) * len(curves)

# Lets do 10 steps
for i in range(iterations):

	# Before we do anything we find out where we should be at this point in time
	step = i

	# Figure out what curve we need to use
	curveId = math.floor(step/split)
	curve = curves[curveId]

	# Set the intensity for a curve
	curve = intensifyCurve(curve, intensities[curveId])

	# Make sure each curve is interpreted start to finish
	step -= (curveId * split)

	# The current curve number for reversing and inversing should be 1-2-3-4
	# 1 is regular
	curveNr = (curveId +1) - (curveId//4)

	# The second and third curves are reversed (the third makes things smaller)
	if curveNr is 2 or curveNr is 3:
		curve = reverseCurve(curve)

	# Before we do anything we find out where we should be at this point in time
	curvePoint = stepSize * step

	# Find the point on the curve for the previous iteration in the loop
	currentPoint = findBezierPoint(curvePoint, curve)

	# This should tell us what the current size of the object is
	currentOffset = (scaleDif * currentPoint[1]) + startSize

	# Now lets find out how much bigger we need to make it
	# We do i+1 because then we start with 1 and end with 10 (0 is nothing anyway)
	step += 1

	# The point along the curve is always a nr between 0.0 and 1.0
	# So we divide 1 by the number of iterations to find the stepsize
	curvePoint =  stepSize * step

	# Find the point on the curve for this iteration in the loop
	newPoint = findBezierPoint(curvePoint, curve)

	# This should be the size we want to achieve
	newOffset = (scaleDif * newPoint[1]) + startSize

	scaleFactor = newOffset / currentOffset

	checkSize *= scaleFactor

	# Lets print out some values to check
	print('')
	print((i+1),step,'curve',curveNr)
	#print('  stepSize',stepSize)
	print('  currentPoint', round(currentPoint[1],5),'newPoint',round(newPoint[1]))
	#print('  currentOffset',currentOffset)
	#print('  newOffset', newOffset)
	print('  scaleFactor', scaleFactor)
	print('  checkSize',checkSize)

	# lets add some meshes so we can see the effect
	bpy.ops.object.duplicate_move(OBJECT_OT_duplicate={"linked":True, "mode":1}, TRANSFORM_OT_translate={"value":(0, 0, 0), "constraint_axis":(False, False, False), "constraint_orientation":'GLOBAL', "mirror":False, "proportional":'DISABLED', "proportional_edit_falloff":'SMOOTH', "proportional_size":1, "snap":False, "snap_target":'CLOSEST', "snap_point":(0, 0, 0), "snap_align":False, "snap_normal":(0, 0, 0), "release_confirm":False})

	xPos = ((newPoint[0]*iterations*2)+(curveId*iterations*2))
	zPos = (newPoint[1]*iterations*2)

	if curveNr == 3 or curveNr == 4:
		zPos -= iterations*2

	bpy.context.active_object.location = (xPos,0.0,zPos)
	bpy.ops.transform.resize(value=(scaleFactor, scaleFactor, scaleFactor), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1, snap=False, snap_target='CLOSEST', snap_point=(0, 0, 0), snap_align=False, snap_normal=(0, 0, 0), release_confirm=False)

Using sine waves

Monday, January 24th, 2011

I’ve recently been using some sine wave math to get nice and smooth results in python for Blender 3D. This page is merely here so I don’t forget what I did, and why.

The basics

The math itself is really simple… as you can see in the image above… the trick is to use this stuff in a “math loop”.

A basic loop moving through a sine wave

  1. # Get the math module
  2. import math
  3.  
  4. # Loop twenty one times (21 because then it starts at 0 and ends with i as 20)
  5. for i in range(21):
  6.  
  7.         # Make a value between 0.0 and 2.0
  8.         x = i * 0.1
  9.  
  10.         # Get the y value
  11.         y = math.sin(math.pi * x)
  12.  
  13.         # Print it out
  14.         print(y)

Display clean python code for copying

# Get the math module
import math

# Loop twenty one times (21 because then it starts at 0 and ends with i as 20)
for i in range(21):

	# Make a value between 0.0 and 2.0
	x = i * 0.1

	# Get the y value
	y = math.sin(math.pi * x)

	# Print it out
	print(y)

A nice increasing curve

  1. # Get the math module
  2. import math
  3.  
  4. # Make a factor so we know how much of an increase each step is
  5. # in this case we want to increase the x value 0.5 in ten steps
  6. factor = (0.5 / 10)
  7.  
  8. # Loop twenty times (range should be 11 so we end up with i as 10)
  9. for i in range(11):
  10.  
  11.         # find out the x position for this value
  12.         x = i * factor
  13.  
  14.         # Multiply by pi
  15.         x = x * math.pi
  16.  
  17.         # but now we add 1.5 * pi because we want the last quarter of the curve
  18.         x = x + (1.5 * math.pi)
  19.  
  20.         # Get the y value
  21.         y = math.sin(x)
  22.  
  23.         # And because we don't want a curve from -1 to 0, but from 0 to 1 we add 1
  24.         y = y + 1
  25.  
  26.         # Print it out
  27.         print(y)

Display clean python code for copying

# Get the math module
import math

# Make a factor so we know how much of an increase each step is
# in this case we want to increase the x value 0.5 in ten steps
factor = (0.5 / 10)

# Loop twenty times (range should be 11 so we end up with i as 10)
for i in range(11):

	# find out the x position for this value
	x = i * factor

	# Multiply by pi
	x = x * math.pi

	# but now we add 1.5 * pi because we want the last quarter of the curve
	x = x + (1.5 * math.pi)

	# Get the y value
	y = math.sin(x)

	# And because we don't want a curve from -1 to 0, but from 0 to 1 we add 1
	y = y + 1

	# Print it out
	print(y)

Making a category based menu with posts in wordpress 2.9.2

Sunday, May 23rd, 2010

I was not entirely happy with the way wordpress handles menus for this (my own) website. I like the idea of making all the content posts so they’re bound to a date and such. Then I’d like to see them in the menu based on the category they’re in. There are category menus, and even nice folding ones, but I couldn’t find one that displays all the posts per category in a nice way.

So I decided to hack one in myself. It’s a very nasty hack… and I just put a bunch of code in the sidebar.php of my template. But that said… it works and I now have a menu that does what I want.

If you’d like to use this… just remember it’s a great big bad hack and very inefficient!

Here’s the html/php code I added to my template’s sidebar.php:

  1. // Get the id of the current post so we can give it a "current" class later.
  2. $postid = $post->ID;
  3.  
  4. // Arguments for getting all the categories
  5. $args = array(
  6. 'show_option_all'    => '',
  7. 'orderby'            => 'name',
  8. 'order'              => 'ASC',
  9. 'show_last_update'   => 0,
  10. 'style'              => 'list',
  11. 'show_count'         => 0,
  12. 'hide_empty'         => 1,
  13. 'use_desc_for_title' => 0,
  14. 'child_of'           => 0,
  15. 'feed'               => '',
  16. 'feed_type'          => '',
  17. 'feed_image'         => '',
  18. 'exclude'            => '',
  19. 'exclude_tree'       => '',
  20. 'include'            => '',
  21. 'hierarchical'       => true,
  22. 'title_li'           => '',
  23. 'number'             => NULL,
  24. 'echo'               => 0,
  25. 'depth'              => 0,
  26. 'current_category'   => 1,
  27. 'pad_counts'         => 0,
  28. 'taxonomy'           => 'category' );
  29.  
  30. // Get all categories (in a silly html menu)
  31. $catmenu = wp_list_categories( $args );
  32.  
  33. // Split the menu to get all categories sepparately
  34. $cats = split('
  35. <li class="cat-item cat-item-', $catmenu);
  36.  
  37. $catmenu = '';
  38.  
  39. // Loop through the categories.
  40. foreach($cats as $key => $cat){
  41.  
  42.         $current = '';
  43.  
  44.         // Get the code and html sepparately
  45.         list($id, $code) = split('"><a', $cat);
  46.  
  47.         // Make sure they're there.
  48.         if($id && $code){
  49.  
  50.                 // If this is the current category, then remove that text and remember for later
  51.                 if(strpos($id, ' current-cat') !== False){
  52.                         $current = ' current-cat';
  53.                         $id = str_replace(' current-cat', '', $id);
  54.                 }
  55.  
  56.                 // In case we got an id... and this category doesn't have sub categories.
  57.                 if(is_numeric($id) && strpos($code, "
  58. <ul class='children'>") === False){
  59.  
  60.                         // Arguments for getting the categorie's posts
  61.                         $args = array(
  62.                                 'post_type' => 'post',
  63.                                 'post_status' => 'published',
  64.                                 'numberposts' => -1,
  65.                                 'category' => $id
  66.                                 );
  67.  
  68.                         // Get the posts
  69.                          $myposts = get_posts($args);
  70.  
  71.                          // If we got any posts returned
  72.                          if(count($myposts)){
  73.  
  74.                                 // Start a nice html post list
  75.                                 $postlist = "\n".'
  76. <ul class="posts">';
  77.  
  78.                                 // Check east post to see if it's current and add to the html
  79.                                  foreach($myposts as $post) {
  80.                                         $current_post = '';
  81.                                         if($postid == $post->ID){
  82.                                                 $current_post = ' class="current-post"';
  83.                                                 $current = ' current-cat';
  84.                                         }
  85.                                         $postlist .= "\n".'
  86. <li'.$current_post.'><a href="'.get_permalink($post->ID).'">'.$post->post_title.'</a></li>
  87.  
  88. ';
  89.                                  }
  90.  
  91.                                  $postlist .= "\n".'</ul>
  92.  
  93. ';
  94.  
  95.                                 // Add the post list to the code of the current category
  96.                                 $code = str_replace('</a>', '</a>'.$postlist, $code);
  97.  
  98.                         }
  99.  
  100.                 }
  101.  
  102.                 // Put everything that was split before back together
  103.                 $cat = '
  104. <li class="cat-item cat-item-'.$id.$current.'"><a'.$code;
  105.  
  106.         }
  107.  
  108.         // Add back into the complete category menu
  109.         $catmenu .= $cat;
  110. }
  111.  
  112. // Print out the category menu
  113. echo '
  114. <li id="menu">
  115. <ul>'.$catmenu.'</ul>
  116. </li>
  117.  
  118. ';

Display clean php code for copying

// Get the id of the current post so we can give it a "current" class later.
$postid = $post->ID;

// Arguments for getting all the categories
$args = array(
'show_option_all'    => '',
'orderby'            => 'name',
'order'              => 'ASC',
'show_last_update'   => 0,
'style'              => 'list',
'show_count'         => 0,
'hide_empty'         => 1,
'use_desc_for_title' => 0,
'child_of'           => 0,
'feed'               => '',
'feed_type'          => '',
'feed_image'         => '',
'exclude'            => '',
'exclude_tree'       => '',
'include'            => '',
'hierarchical'       => true,
'title_li'           => '',
'number'             => NULL,
'echo'               => 0,
'depth'              => 0,
'current_category'   => 1,
'pad_counts'         => 0,
'taxonomy'           => 'category' );

// Get all categories (in a silly html menu)
$catmenu = wp_list_categories( $args );

// Split the menu to get all categories sepparately
$cats = split('
  • ") === False){ // Arguments for getting the categorie's posts $args = array( 'post_type' => 'post', 'post_status' => 'published', 'numberposts' => -1, 'category' => $id ); // Get the posts $myposts = get_posts($args); // If we got any posts returned if(count($myposts)){ // Start a nice html post list $postlist = "\n".'
      '; // Check east post to see if it's current and add to the html foreach($myposts as $post) { $current_post = ''; if($postid == $post->ID){ $current_post = ' class="current-post"'; $current = ' current-cat'; } $postlist .= "\n".' '.$post->post_title.' '; } $postlist .= "\n".'
    '; // Add the post list to the code of the current category $code = str_replace('', ''.$postlist, $code); } } // Put everything that was split before back together $cat = '
    • '.$catmenu.'
  • ';

    And here is the javascript code I added to my template’s header.php:

    1. // Initialise javascript functions using jquery
    2. jQuery(document).ready(function(){
    3.  
    4.         initMenu();
    5.  
    6. });
    7.  
    8. // Start the menu functionality
    9. function initMenu(){
    10.         // Hide all the submenus by default
    11.         jQuery('#menu ul ul').hide();
    12.  
    13.         // Find the current post and make sure all the categories it's in are also "current", then show their kids.
    14.         jQuery('#menu .current-post').parents('li[id!=menu]').addClass('current-cat').children('ul').show();
    15.  
    16.         // Replace the click event of all category menu items except for "news"
    17.         // In stead make them fold down and up the sub menu
    18.         jQuery('#menu a').click(function(event){
    19.  
    20.                 thisItem = jQuery(this);
    21.  
    22.                 childList = thisItem.siblings('ul');
    23.  
    24.                 if(childList.length){
    25.  
    26.                         if(!(thisItem.html() == 'News' && childList.is(':hidden'))){
    27.  
    28.                                 event.preventDefault();
    29.  
    30.                                 if(childList.is(':hidden')){
    31.  
    32.                                         thisItem.addClass('clicked');
    33.  
    34.                                         childList.slideDown('fast');
    35.  
    36.                                         jQuery('#menu ul:visible').each(function(){
    37.  
    38.                                                 if(!(jQuery('.clicked', this).length || jQuery(this).siblings('.clicked').length)){
    39.                                                         jQuery(this).slideUp('fast');
    40.                                                 }
    41.  
    42.                                         });
    43.  
    44.                                         thisItem.removeClass('clicked');
    45.  
    46.                                 }else{
    47.                                         childList.slideUp('fast');
    48.                                 }
    49.                         }
    50.  
    51.                 }
    52.  
    53.         });
    54. }

    Display clean javascript code for copying

    // Initialise javascript functions using jquery
    jQuery(document).ready(function(){
    
    	initMenu();
    
    });
    
    // Start the menu functionality
    function initMenu(){
    	// Hide all the submenus by default
    	jQuery('#menu ul ul').hide();
    
    	// Find the current post and make sure all the categories it's in are also "current", then show their kids.
    	jQuery('#menu .current-post').parents('li[id!=menu]').addClass('current-cat').children('ul').show();
    
    	// Replace the click event of all category menu items except for "news"
    	// In stead make them fold down and up the sub menu
    	jQuery('#menu a').click(function(event){
    
    		thisItem = jQuery(this);
    
    		childList = thisItem.siblings('ul');
    
    		if(childList.length){
    
    			if(!(thisItem.html() == 'News' && childList.is(':hidden'))){
    
    				event.preventDefault();
    
    				if(childList.is(':hidden')){
    
    					thisItem.addClass('clicked');
    
    					childList.slideDown('fast');
    
    					jQuery('#menu ul:visible').each(function(){
    
    						if(!(jQuery('.clicked', this).length || jQuery(this).siblings('.clicked').length)){
    							jQuery(this).slideUp('fast');
    						}
    
    					});
    
    					thisItem.removeClass('clicked');
    
    				}else{
    					childList.slideUp('fast');
    				}
    			}
    
    		}
    
    	});
    }

    Teaching UV unwrapping

    Thursday, March 18th, 2010

    Getting to grips with 2D to 3D

    This is a simple little exercise I came up with for showing students how to convert 2D to 3D and vise versa. The idea is to not go straight to 3D, but in stead give them a hands-on task that gets the idea into their heads. It’s not a completely new thing for most students, but the relation to UV unwrapping is. And of course it is fun to try to make it challenging as well.


    The example

    To give my students some idea of what I expected them to do I showed them an example I made the night before class. It’s a basic svg I made in Inkscape that I printed on A4 paper.

    I could have just made a single T shape to make a single cube, but since I was teaching university level students that was a bit too simple. In stead I made this, which turns into 2 cubes that are connected at a corner. The real world result that I glued together the night before class, and showed my students in the morning is below here.


    The task

    After showing the students my example, I provided them all with paper, rulers, pencils, glue or tape, and scissors. Then put them right to work. The task I gave them was was rather simple…

    Make something more complicated than a single cube!


    The results

    As usual my students surprised me with their inventiveness. The range of designs they came up with was really nice. Especially the surprises and “misinterpretations” that I really didn’t see coming. All I did during the class was walk around and give some pointers.


    Round up

    That’s basicly all this class was. After finishing the exercise we got stuck in in Blender 3D to UV unwrap the models they had made the day before. It was a lot easier for me to teach them that technique after they had done exactly the opposite with paper (which is what this exercise is). All in all this was a fun hour to break up the week of staring at computer screens, and I’ll definitely repeat it in future.

    I hope this helps you, and if you have similar fun ways of teaching your students, please let me know. I’m always looking for novel ways of getting these complex ideas into students heads.

    Dolf

    Getting python to work on Xampp

    Wednesday, March 17th, 2010

    I spent most of today (Dec 14 2009) messing around trying to get xampp to interpret python scripts. Usually xampp only works with php, at least on my windows system (windows 32 bit vista). But since I’m developing something for a python server I needed to get it to work.

    I read a lot, found a heap of documentation about mod_python (mod_python.so), and only after half a day found out that that’s really not a very nice solution. And I already had python 2.5 installed as well. mod_python seems nice, and has a lot of links to it on google, but it’s overkill/weird and rarely needed.

    So, if you’re like me, and have python & xampp installed on your system (and your pythonpath set in the environment variables), and need .py files to work… just do this.


    Configuring the server

    In the httpd.conf file for your apache installation (part of xampp) add the following all the way at the bottom. In my case the httpd.conf can be found here: C:\xampp\apache\conf

    1. #
    2. # For Python
    3. #
    4. AddHandler cgi-script .py
    5. ScriptInterpreterSource Registry-Strict

    Display clean text code for copying

    #
    # For Python
    #
    AddHandler cgi-script .py
    ScriptInterpreterSource Registry-Strict

    Configuring the python script

    Then in the top of the python script on your server, it already knows it should be python, but it doesn’t know yet where the python program is. So as the very first line in your python scripts on the server you have to say where python is installed. In my case that looks like this

    1. #!C:/Python25/python.exe

    Display clean python code for copying

    #!C:/Python25/python.exe

    Enabling index.py

    Of course it’s nice to have index.py files work just like index.php ones as well. So I added index.py to the following bit in the httpd.conf

    1. #
    2. # DirectoryIndex: sets the file that Apache will serve if a directory
    3. # is requested.
    4. #
    5. <IfModule dir_module>
    6.     DirectoryIndex index.php index.php4 index.php3 index.cgi index.pl index.html index.htm index.shtml index.phtml index.py
    7. </IfModule>

    Display clean text code for copying

    #
    # DirectoryIndex: sets the file that Apache will serve if a directory
    # is requested.
    #
    <IfModule dir_module>
        DirectoryIndex index.php index.php4 index.php3 index.cgi index.pl index.html index.htm index.shtml index.phtml index.py
    </IfModule>

    That’s it

    Now .py files are also interpreted by python on a xampp installed apache server, just like .php. I hope that helps you as much as it dit me, and maybe saves you some time.

    Dolf

    Shorten text

    Wednesday, March 17th, 2010

    This is a small function that shortens a string.
    It looks if the string is longer than a preset length, and if so cuts the text there.
    Then it removes the last word from the string (so your string ends neatly at a space), and adds three dots.

    1. // Shorten a text if nessecary
    2. function shortenText($txt='', $len=0){
    3.  
    4.         if(strlen($txt) > $len){
    5.  
    6.                 $txt = substr($txt, 0, $len);
    7.  
    8.                 $t = split("[\n\r\t ]+", $txt);
    9.                 $t = array_slice($t, 0, -1);
    10.                 $txt = join(' ', $t);
    11.  
    12.                 $txt .= '...';
    13.  
    14.         }
    15.  
    16.         return $txt;
    17. }

    Display clean php code for copying

    // Shorten a text if nessecary
    function shortenText($txt='', $len=0){
    
    	if(strlen($txt) > $len){
    
    		$txt = substr($txt, 0, $len);
    
    		$t = split("[\n\r\t ]+", $txt);
    		$t = array_slice($t, 0, -1);
    		$txt = join(' ', $t);
    
    		$txt .= '...';
    
    	}
    
    	return $txt;
    }

    Rot13

    Wednesday, March 17th, 2010

    Basic rot13 function for PHP (remember that this is NOT secure encryption!).
    It’s built into php nowadays, but if you have an old version you may not.

    1. // Rot 13 function for older php versions
    2. function rot13($text){
    3.         $length = strlen($text);
    4.         $newtext = '';
    5.          for($i = 0; $i < $length; $i++){
    6.                  $index = ord($text[$i]);
    7.                  // Rotate upper case.
    8.                  if($index > 64 && $index < 91){
    9.                          $index += 13;
    10.                          if($index > 90) $index -= 26;
    11.                          $newtext .= chr($index);
    12.                 // Rotate lower case.
    13.                 }elseif($index > 96 && $index < 123){
    14.                         $index += 13;
    15.                         if($index > 122) $index -= 26;
    16.                         $newtext .= chr($index);
    17.                  }else{ $newtext .= $text[$i]; }
    18.          }
    19.          return $newtext;
    20. }

    Display clean php code for copying

    // Rot 13 function for older php versions
    function rot13($text){
    	$length = strlen($text);
    	$newtext = '';
    	 for($i = 0; $i < $length; $i++){
    		 $index = ord($text[$i]);
    		 // Rotate upper case.
    		 if($index > 64 && $index < 91){
    			 $index += 13;
    			 if($index > 90) $index -= 26;
    			 $newtext .= chr($index);
    		// Rotate lower case.
    		}elseif($index > 96 && $index < 123){
    			$index += 13;
    			if($index > 122) $index -= 26;
    			$newtext .= chr($index);
    		 }else{ $newtext .= $text[$i]; }
    	 }
    	 return $newtext;
    }

    Make a random string

    Wednesday, March 17th, 2010

    This is a tiny function that makes a random string of predefined length.
    It does not use letters and numbers that could be confusing, like O and 0.

    1. // Make a random string
    2. function makeRandomString($length){
    3.         $str = array('a', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', '2', '4', '5', '6', '7', '8', '9');
    4.         $nkeys = array_rand($str, $length);
    5.         $nstr = '';
    6.         foreach($nkeys as $key){ $nstr .= $str[$key]; }
    7.         return $nstr;
    8. }

    Display clean php code for copying

    // Make a random string
    function makeRandomString($length){
    	$str = array('a', 'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r', 's', 't', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'W', 'X', 'Y', 'Z', '2', '4', '5', '6', '7', '8', '9');
    	$nkeys = array_rand($str, $length);
    	$nstr = '';
    	foreach($nkeys as $key){ $nstr .= $str[$key]; }
    	return $nstr;
    }

    Make image version

    Wednesday, March 17th, 2010

    This is a function I use to make multiple versions such as thumbnails of uploaded images.
    There’s three methods for resizing available in it (mask, fit & limit).

    1. // Function for making a new resized copy of a file
    2. // mask makes the shortest edge match the mask, so it will be bigger than the mask, always resizes!
    3. // fit makes the longest edge match, always resizes!
    4. // limit makes the image fit, but won't stretch if it's smaller.
    5. function makeImageVersion($newWidth, $newHeight, $filePath, $newName, $fileExtension, $method){
    6.  
    7.         // Find out the original size of the image
    8.         list($wO, $hO) = getimagesize($filePath);
    9.  
    10.         // Get the ratios it would take to resize
    11.         $wR = $newWidth / $wO;
    12.         $hR = $newHeight / $hO;
    13.  
    14.         // Figure out which ratio we need
    15.         switch($method){
    16.                 case 'mask':
    17.                         if($wR > $hR){ $ratio = $wR; }
    18.                         else{ $ratio = $hR; }
    19.                         break;
    20.                 case 'limit':
    21.                         if($wR < 1 && $wR < $hR){ $ratio = $wR; }
    22.                         elseif($hR < 1){ $ratio = $hR; }
    23.                         else{ $ratio = 1; }
    24.                         break;
    25.                 case 'fit':
    26.                 default:
    27.                         if($wR > $hR){ $ratio = $hR; }
    28.                         else{ $ratio = $wR; }
    29.                         break;
    30.         }
    31.  
    32.         $wN = round($wO * $ratio);
    33.         $hN = round($hO * $ratio);
    34.  
    35.         $iP = imagecreatetruecolor($wN, $hN);
    36.         imageAlphaBlending($iP, false);
    37.         imageSaveAlpha($iP, true);
    38.  
    39.         if($fileExtension == 'jpg'){ $iI = imagecreatefromjpeg($filePath); }
    40.         elseif($fileExtension == 'png'){        $iI = imagecreatefrompng($filePath); }
    41.         else{ $iI = imagecreatefromgif($filePath); }
    42.  
    43.         imagecopyresampled($iP, $iI, 0, 0, 0, 0, $wN, $hN, $wO, $hO);
    44.  
    45.         if($fileExtension == 'jpg'){ imagejpeg($iP, $newName, 90); }
    46.         elseif($fileExtension == 'png'){ imagepng($iP, $newName); }
    47.         else{ imagegif($iP, $newName); }
    48. }

    Display clean php code for copying

    // Function for making a new resized copy of a file
    // mask makes the shortest edge match the mask, so it will be bigger than the mask, always resizes!
    // fit makes the longest edge match, always resizes!
    // limit makes the image fit, but won't stretch if it's smaller.
    function makeImageVersion($newWidth, $newHeight, $filePath, $newName, $fileExtension, $method){
    
    	// Find out the original size of the image
    	list($wO, $hO) = getimagesize($filePath);
    
    	// Get the ratios it would take to resize
    	$wR = $newWidth / $wO;
    	$hR = $newHeight / $hO;
    
    	// Figure out which ratio we need
    	switch($method){
    		case 'mask':
    			if($wR > $hR){ $ratio = $wR; }
    			else{ $ratio = $hR; }
    			break;
    		case 'limit':
    			if($wR < 1 && $wR < $hR){ $ratio = $wR; }
    			elseif($hR < 1){ $ratio = $hR; }
    			else{ $ratio = 1; }
    			break;
    		case 'fit':
    		default:
    			if($wR > $hR){ $ratio = $hR; }
    			else{ $ratio = $wR; }
    			break;
    	}
    
    	$wN = round($wO * $ratio);
    	$hN = round($hO * $ratio);
    
    	$iP = imagecreatetruecolor($wN, $hN);
    	imageAlphaBlending($iP, false);
    	imageSaveAlpha($iP, true);
    
    	if($fileExtension == 'jpg'){ $iI = imagecreatefromjpeg($filePath); }
    	elseif($fileExtension == 'png'){	$iI = imagecreatefrompng($filePath); }
    	else{ $iI = imagecreatefromgif($filePath); }
    
    	imagecopyresampled($iP, $iI, 0, 0, 0, 0, $wN, $hN, $wO, $hO);
    
    	if($fileExtension == 'jpg'){ imagejpeg($iP, $newName, 90); }
    	elseif($fileExtension == 'png'){ imagepng($iP, $newName); }
    	else{ imagegif($iP, $newName); }
    }
    click here to close

    Help keep these files free,
    and support further development!