# python画平面直角坐标系_一棵树-可视化之图形化基础之向量

const ctx = canvas.getContext('2d')

// 我们这里把原点定位在canvas左下角

ctx.translate(0, canvas.height)

// 关键步骤： 将canvasY轴方向翻转

ctx.scale(1, -1)

width="512"

height="256"

style="display: block;margin: 0 auto;background-color: #ccc"

>

const canvas = document.querySelector('canvas')

const rc = rough.canvas(canvas)

rc.ctx.translate(0, canvas.height)

rc.ctx.scale(1, -1)

const cSun = [canvas.width / 2, 106]

const diameter = 100 // 直径

const hill1Points = {

start: [76, 0], // 起始点

top: [176, 100], // 顶点

end: [276, 0] // 终点

}

const hill2Points = {

start: [236, 0], // 起始点

top: [336, 100], // 顶点

end: [436, 0] // 终点

}

const hill1Options = {

roughness: 0.8,

stokeWidth: 2,

fill: 'pink'

}

const hill2Options = {

roughness: 0.8,

stokeWidth: 2,

fill: 'chocolate'

}

function createHillPath(point) {

const { start, top, end } = point

return M${start[0]}${start[1]}L${top[0]}${top[1]}L${end[0]}${end[1]}

}

function paint() {

rc.path(createHillPath(hill1Points), hill1Options)

rc.path(createHillPath(hill2Points), hill2Options)

rc.circle(cSun[0], cSun[1], diameter, {

stroke: 'red',

strokeWidth: 4,

fill: 'rgba(255, 255, 0, 0.4)',

fillStyle: 'solid'

})

}

paint()

(是不是也能在画展上卖个不错的价格)

const v = new Vector2D(1, 10)

const dir = Math.atan2(v.y, v.x)

v1(x1, y1) + v2(x2, y2) = v3(x1 + x2, y1 + y2)

va vb = va.length vb.length * cos(rad)叉乘示意图：

va vb = va.length va.length * sin(rad)

class Vector2D extends Array {

constructor(x = 1, y = 0) {

super(x, y)

}

get x() {

return this[0]

}

get y() {

return this[1]

}

set x(v) {

this[0] = v

}

set y(v) {

this[1] = v

}

this.x = this.x + v.x

this.y = this.y + v.y

return this

}

length() {

return Math.hypot(this.x, this.y)

}

const c = Math.cos(rad)

const s = Math.sin(rad)

const [x, y] = this

this.x = x * c + y * -s

this.y = x * s + y * c

return this

}

}

...

width="512"

height="512"

style="display:block;margin:0 auto;background-color: #ccc"

>

...

const ctx = canvas.getContext('2d')

ctx.translate(0, canvas.height)

ctx.scale(1, -1)定义绘制树枝的方法/**

* 1. ctx canvas ctx 上下文对象

* 2. 起始向量

* 3. length 向量长度(树枝长度)

* 4. thickness 线段宽度

* 5. 单位向量 dir 旋转角度

* 6. bias 随机因子

*/

const canvas = document.querySelector('canvas')

const ctx = canvas.getContext('2d')

ctx.translate(0, canvas.height)

ctx.scale(1, -1)

ctx.lineCap = 'round'

console.log(canvas.width)

const v0 = new Vector2D(canvas.width / 2, 0)

function drawBranch(ctx, v0, length, thickness, rad, bias) {

const v = new Vector2D().rotate(rad).scale(length)

const v1 = v0.copy().add(v)

ctx.beginPath()

ctx.lineWidth = thickness

ctx.moveTo(...v0)

ctx.lineTo(...v1)

ctx.stroke()

ctx.closePath()

}

// 定义好了之后我们先画一个树枝试试看

drawBranch(ctx, v0, 50, 10, Math.PI / 2, 1)递归画图// 先定义收缩系数

const LENGTH_SHRINK = 0.9

const THICKNESS_SHRINK = 0.8

const RAD_SHRINK = 0.5

const BIAS_SHRINK = 1

function drawBranch(ctx, v0, length, thickness, rad, bias) {

// ....

if (thickness > 2) {

// 画左树枝

const left =

Math.PI / 4 +

drawBranch(

ctx,

v1,

length * LENGTH_SHRINK,

thickness * THICKNESS_SHRINK,

left,

bias

)

// 画右树枝

const right = Math.PI / 4 + RAD_SHRINK * (rad - 0.2)

drawBranch(

ctx,

v1,

length * LENGTH_SHRINK,

thickness * THICKNESS_SHRINK,

right,

bias

)

}

}

drawBranch(ctx, v0, 50, 10, Math.PI / 2, 1)

// ....

if (thickness > 2) {

// 画左树枝

const left =

Math.PI / 4 + RAD_SHRINK * (rad + 0.2) + bias * (Math.random() - 0.5) // 加些随机数

drawBranch(

ctx,

v1,

length * LENGTH_SHRINK,

thickness * THICKNESS_SHRINK,

left,

bias

)

// 画右树枝

const right =

Math.PI / 4 + RAD_SHRINK * (rad - 0.2) + bias * (Math.random() - 0.5) // 加些随机数

drawBranch(

ctx,

v1,

length * LENGTH_SHRINK,

thickness * THICKNESS_SHRINK,

right,

bias

)

}

}

drawBranch(ctx, v0, 50, 10, Math.PI / 2, 1)

(是不是有点艺术内味儿了)

// .....

if (thickness < 5 && Math.random() < 0.3) {

const th = 6 + Math.random()

ctx.save()

ctx.strokeStyle = '#e4393c'

ctx.lineWidth = th

ctx.beginPath()

ctx.moveTo(...v1)

ctx.lineTo(v1.x, v1.y + 2)

ctx.stroke()

ctx.closePath()

ctx.restore()

}

}

drawBranch(ctx, v0, 50, 10, Math.PI / 2, 3) // 这里增大了随机因子， 让树枝更加分散

(我再问一遍， 是不是很好看， 是不是很想花个几百万小钱买下它)

09-19

04-09 5540
04-15 7976
07-22 1万+
01-08 1万+
09-15 6485
05-07 6688
02-10 673
11-01 6063
03-20 2万+
09-03 1万+
©️2020 CSDN 皮肤主题: 1024 设计师:白松林