找回密码
 快速注册
搜索
查看: 3991|回复: 16

有人用过TikzEdt之类的不?

[复制链接]

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

kuing 发表于 2015-11-16 14:50 |阅读模式
TikzEdt 看起来是个可以直观 tikz 作图的东东,主页:tikzedt.org/



有人玩过吗?介绍一下怎么用?或者推荐一些类似的软件?

点评

Checking for new version ...
Checking for new version failed: The remote server returned an error: (404) Not Found.  发表于 2022-12-15 04:40

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2015-11-16 15:16
回复 1# kuing

网友给我介绍过一个叫qtikz的软件,好像是在linux里用的,我没用过,不知是不是版主所说的那类软件。

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2015-11-16 15:33
回复 2# abababa

看了下,似乎跟下面那种预览器差不多,跟1#的差了右边那些
主页:hackenberger.at/blog/ktikz-editor-for-the-tikz-language/

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2015-11-16 15:41
回复 3# kuing

我这里打不开版主发的那个软件的网址,不知道怎么回事。

730

主题

1万

回帖

9万

积分

积分
93593
QQ

显示全部楼层

 楼主| kuing 发表于 2015-11-16 15:45
回复 4# abababa

或许是被qiang了……

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2015-11-16 15:49
回复 5# kuing

哦,图片能看到一半,看不全,看到版主所说的那些了,是类似快捷按钮之类的吧?点一下就出来代码了。

15

主题

958

回帖

1万

积分

积分
12454

显示全部楼层

色k 发表于 2015-11-29 01:50

413

主题

1558

回帖

1万

积分

积分
11498

显示全部楼层

abababa 发表于 2015-11-29 09:55
觉得geogebra能把自动生成的代码做得好点就好了,用软件画几何题里的图挺方便的,不过看tikz不只是画几何图,还有很多其它的,有的可能是叫流程图吧?我也不太懂这名词。

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2022-12-13 18:20

ArcEditTool出错,如何解决呢

Quicker_20221213_101832.png

17

主题

127

回帖

1822

积分

积分
1822

显示全部楼层

uk702 发表于 2022-12-13 21:49
可考虑用  svgo (github.com/svg/svgo) 压缩 geogebra 生成的 svg 文件,比如这个文件,由 28k 压缩成 9k。简单文件一般可压缩为约 2~5k 左右。

命令:svgo 32765321.svg

32765321.svg:
Done in 95 ms!
28.279 KiB - 67.4% = 9.217 KiB
Snipaste_2022-12-13_21-47-16.png
$type

32765321.svg

28.28 KB, 下载次数: 3

3149

主题

8386

回帖

6万

积分

$\style{scale:11;fill:#eff}꩜$

积分
65391
QQ

显示全部楼层

hbghlyj 发表于 2022-12-13 22:04
uk702 发表于 2022-12-13 14:49
可考虑用  svgo (github.com/svg/svgo) 压缩 geogebra 生成的 svg 文件,比如这个文件,由 28k 压 ...


相关帖子
Web版GeoGebra导出Tikz
[python3]ggb导出为tikz

点评

没太看懂怎么使用,比如说 ggb.py 怎么用啊?python ggb.py 或者 python ggb.py 3276532.ggb 均没有任何输出。  发表于 2022-12-13 22:19

17

主题

127

回帖

1822

积分

积分
1822

显示全部楼层

uk702 发表于 2022-12-13 22:26
本帖最后由 uk702 于 2022-12-13 22:35 编辑
hbghlyj 发表于 2022-12-13 22:04
相关帖子
Web版GeoGebra导出Tikz
ggb导出为tikz


我个人更希望继续使用 svg 格式,上面那个 28k 的 svg 文件还可以继续压缩成 6k,简单图形压缩成5k以下我想多数场合都能接受,如果继续优化代码,应该还能继续压缩,上面那个 28k 的 svg 文件,我用我修改的程序将它压缩为 6k。

进一步压缩可能要改 svg 语法了,比如用 w 和 h 来代替 width、height 之类的(我不太懂 svg,不知道能否用 w/h 来代替 width/height),或者重写并合并各个模式和它的参数。

Tikz 使用的人估计太少了,并且能够将之整合到网页之中的人应该少之又少。

17

主题

127

回帖

1822

积分

积分
1822

显示全部楼层

uk702 发表于 2022-12-14 09:50
uk702 发表于 2022-12-13 22:26
我个人更希望继续使用 svg 格式,上面那个 28k 的 svg 文件还可以继续压缩成 6k,简单图形压缩成5k以下我 ...

同时发现 geogebra 生成的 svg 文件过大在主要原因是因为它用 path 来显示各个 label,如果能将之换成 text 语句的话,就能大大减少 svg 的大小,我正在做一些尝试,希望能搞定。

17

主题

127

回帖

1822

积分

积分
1822

显示全部楼层

uk702 发表于 2022-12-14 14:05
本帖最后由 uk702 于 2022-12-14 15:11 编辑 用 golang 写了一段代码,初步测试效果 ok. 前面那个 28k 的 svg 文件,进一步压缩到 4k 。

  1. package main
  2. import (
  3.         "fmt"
  4.         "io/ioutil"
  5.         "os"
  6.         "os/exec"
  7.         "regexp"
  8.         "strings"
  9.         "strconv"
  10.         "unsafe"
  11.         "github.com/PuerkitoBio/goquery"
  12. )
  13. // svgo compress,主要代码
  14. func sc(fname string) {
  15.                 // 读入文件
  16.                 input, err := ioutil.ReadFile(fname)
  17.                 content := string(input)
  18.                 // goquery 似乎不支持 dom.Find(`clipPath`)??? 故人为地改成 aaaaa
  19.                 content = strings.Replace(content, "clipPath", "aaaaa", -1)
  20.                 // 将 <g clip-path="...> 更改为 <g>,似乎没有影响,但不确认
  21.                 re, _ := regexp.Compile(` clip-path="[^"].*"`)
  22.                 content = re.ReplaceAllString(content, "")
  23.                 // 下面  30~60 行,读取 viewBox 的 width 和 height 参数,写入变量 v1 与 v2 之中
  24.                 // 当 svg 里的元素位置超出 viewBox 时,将之删除
  25.                 s := strings.Index(content, "viewBox=")
  26.                 i := s+1
  27.                 k := 0
  28.                 for k != 2 {
  29.                         if input[i] == ' ' {
  30.                                 k++
  31.                         }
  32.                         i++
  33.                 }
  34.                 n := i
  35.                 for content[n] != ' ' {
  36.                         n++
  37.                 }
  38.                 s1 := content[i:n]
  39.                 n++
  40.                 i = n
  41.                 for content[n] != '"' {
  42.                         n++
  43.                 }
  44.                 s2 := content[i:n]
  45.                 v1, _ := strconv.ParseFloat(string(s1), 32)
  46.                 v2, _ := strconv.ParseFloat(string(s2), 32)
  47.                 // fmt.Println(v1, v2)
  48.                 // 使用 goquery 解析 svg 文件
  49.                 dom, err := goquery.NewDocumentFromReader(strings.NewReader(content))
  50.                
  51.                 // 删除嵌入的图片
  52.                 dom.Find(`image`).Each(func(i int, s *goquery.Selection) {
  53.                                 parent := s.Parent()
  54.                                 parent.Get(0).RemoveChild(s.Get(0))
  55.                 })
  56.                 // 删除 <clipPath ...>xxxx</clipPath>,删除似乎没有影响,但不确认
  57.                 // goquery 似乎不支持 dom.Find(`clipPath`)??? 故人为地改成 aaaaa
  58.                 dom.Find(`aaaaa`).Each(func(i int, s *goquery.Selection) {
  59.                                 parent := s.Parent()
  60.                                 parent.Get(0).RemoveChild(s.Get(0))
  61.                 })
  62.                 dom.Find(`path`).Each(func(i int, s *goquery.Selection) {
  63.                         parent := s.Parent()
  64.                         str, _ := parent.Html()
  65.                         // 这段代码实现将用 path 来表现的文字(如点的 label)改成用 <text>xxx</text> 来表示
  66.                         // 其中的 x、y 位置由 path 的第一个参数 M xxx yyy 中的 xxx、yyy 得到
  67.                         // 实践证明多数情况下没问题,但某些情形时有约 10 个点位的偏差,原因未明
  68.                         if strings.Index(str, "<path d=\"M") >= 0 {
  69.                                 reg := regexp.MustCompile(`<path d="M ([\-0-9.]+) ([\-0-9.]+)`)
  70.                                 p := reg.FindStringSubmatch(str)
  71.                                 if len(p) > 1 {
  72.                                         d1, _ := strconv.ParseFloat(string(p[1]), 32)
  73.                                         d2, _ := strconv.ParseFloat(string(p[2]), 32)
  74.                                         if d1 > v1 || d2 > v2 {
  75.                                                 // 这种情况下的元素位于 viewBox 之外,删除
  76.                                                 parent.Get(0).RemoveChild(s.Get(0))
  77.                                         } else if len(str) > 300 && strings.Index(str, "Q ") >0 {
  78.                                                 // 根据 title 或 desc 来获得当前元素的标签
  79.                                                 reg := regexp.MustCompile(`<title>(.*)</title>.*\n.*<desc>(.*)</desc>`)
  80.                                                 p := reg.FindStringSubmatch(str)
  81.                                                 if len(p) > 0 {
  82.                                                         label := p[1]
  83.                                                         i := strings.Index(label, " ")
  84.                                                         if i >= 0 {
  85.                                                                 label = label[i+1:]
  86.                                                                 //fmt.Println("#" + p[1][:i] + "#")
  87.                                                         if p[1][:i] == "点" {
  88.                                                                         st := fmt.Sprintf(`<text x="%.2f" y="%.2f">%s</text>`, d1, d2, label)
  89.                                                                         parent.SetHtml(st)
  90.                                                                         //fmt.Println(p[1])
  91.                                                                 }
  92.                                                         } else {
  93.                                                                         st := fmt.Sprintf(`<text x="%.2f" y="%.2f">%s</text>`, d1, d2, p[2])
  94.                                                                         parent.SetHtml(st)
  95.                                                         }
  96.                                                 }
  97.                                         }
  98.                                 }
  99.                         }
  100.                 })
  101.                 // 写回文件
  102.                 dom.Find(`html`).Each(func(i int, selection *goquery.Selection) {
  103.                         outstr, _ := selection.Html()
  104.                         ioutil.WriteFile(fname, []byte(outstr[19:len(outstr)-29]), 0666)
  105.                 })
  106. }
  107. // 用法:sc.exe xxx.svg
  108. func main() {
  109.         fname := "C:\\Temp\\geogebra.svg"
  110.         if len(os.Args) > 1 {
  111.                         fname = os.Args[1]
  112.                         fmt.Println(fname)
  113.         }        
  114.         // 调用压缩函数
  115.         sc(fname)
  116.         // 调第三方工具 svgo 进行第二轮优化
  117.         cmd := exec.Command("C:\\...\\npm\\svgo.cmd", fname)
  118.         cmd.Run()       
  119. }
复制代码

评分

参与人数 1威望 +2 收起 理由
hbghlyj + 2 很有用!

查看全部评分

17

主题

127

回帖

1822

积分

积分
1822

显示全部楼层

uk702 发表于 2022-12-15 06:56
本帖最后由 uk702 于 2022-12-15 07:16 编辑 声明:这里的优化专用于 geogebra 导出的 svg 优化,不适用其它 svg 文件,也不能重复应用于已经优化过的 geogebra 导出的 svg 。

更进一步,画各个点的代码改用 <circle> 语句,原来的 28k 文件现在进一步压缩为 2k,而整个图形(近乎)保持不变。

这里说的近乎保持不变(已知问题),主要有以下几点:
1)小数点精度这里始终保持 2 位;
2)不再区分自由点和非自由点,每个点始终用 blue 填充;
3)  某些点的位置及大小(font-size)发生微小变化。(bug,一般,暂时视作可忽略)
4)中文文本或 latex 文本内容可能显示会有些问题。(bug, 严重,暂时视作规避并待改进)

新代码如下(func main 不变就不贴出了)

  1. func sc(fname string) {
  2.         input, err := ioutil.ReadFile(fname)
  3.         content := string(input)
  4.         prevx, prevy := 0.0, 0.0
  5.        
  6.         // 这里 content 和 input 能保持一致,但后面对 content 进行 replace 之后,就不一致了
  7.         s := strings.Index(content, "viewBox=")
  8.         i := s+1
  9.         k := 0
  10.         for k != 2 {
  11.                 if input[i] == ' ' {
  12.                         k++
  13.                 }
  14.                 i++
  15.         }
  16.        
  17.         n := i
  18.         for content[n] != ' ' {
  19.                 n++
  20.         }
  21.         s1 := content[i:n]
  22.         n++
  23.         i = n
  24.         for content[n] != '"' {
  25.                 n++
  26.         }
  27.         s2 := content[i:n]
  28.         //fmt.Println(s1, s2)
  29.         v1, _ := strconv.ParseFloat(string(s1), 32)
  30.         v2, _ := strconv.ParseFloat(string(s2), 32)
  31.         // fmt.Println(v1, v2)
  32.         content = strings.Replace(content, "clipPath", "aaaaa", -1)
  33.         content = strings.Replace(content, `stroke-linecap="round"`, "", -1)
  34.         content = strings.Replace(content, `stroke-linejoin="round"`, "", -1)
  35.         re, _ := regexp.Compile(` clip-path="[^"].*"`)
  36.         content = re.ReplaceAllString(content, "")
  37.         re, _ = regexp.Compile(`\.(\d\d)(\d+)`)
  38.         content = re.ReplaceAllString(content, ".$1")
  39.         dom, err := goquery.NewDocumentFromReader(strings.NewReader(content))
  40.        
  41.         // 筛选含有transform属性的g元素并删除
  42.         // dom.Find(`g[transform]`).Each(func(i int, s *goquery.Selection) {
  43.         //   parent := s.Parent()
  44.         //   parent.Get(0).RemoveChild(s.Get(0))
  45.         // })
  46.        
  47.         dom.Find(`image`).Each(func(i int, s *goquery.Selection) {
  48.                 parent := s.Parent()
  49.                 parent.Get(0).RemoveChild(s.Get(0))
  50.         })
  51.         // 似乎不支持 dom.Find(`clipPath`),故先人为改成 aaaaa
  52.         dom.Find(`aaaaa`).Each(func(i int, s *goquery.Selection) {
  53.                 parent := s.Parent()
  54.                 parent.Get(0).RemoveChild(s.Get(0))
  55.         })
  56.         dom.Find(`path`).Each(func(i int, s *goquery.Selection) {
  57.                 parent := s.Parent()
  58.                 str, _ := parent.Html()
  59.                 if strings.Index(str, "<path d=\"M") >= 0 {
  60.                         dstr, _ := s.Attr("d")
  61.                        
  62.                         reg := regexp.MustCompile(`<path d="M ([\-0-9.]+) ([\-0-9.]+)`)
  63.                         p := reg.FindStringSubmatch(str)
  64.                         if len(p) > 1 {
  65.                                 d1, _ := strconv.ParseFloat(string(p[1]), 32)
  66.                                 d2, _ := strconv.ParseFloat(string(p[2]), 32)
  67.                                 if d1 > v1 || d2 > v2 {
  68.                                         //fmt.Println(d1, v1, d2, v2)
  69.                                         parent.Get(0).RemoveChild(s.Get(0))
  70.                                 } else if strings.Index(dstr, "Q ") > 0 {
  71.                                         reg := regexp.MustCompile(`<title>(.*)</title>.*\n.*<desc>(.*)</desc>`)
  72.                                         p := reg.FindStringSubmatch(str)
  73.                                         if len(p) > 0 {
  74.                                                 label := p[1]
  75.                                                 i := strings.Index(label, " ")
  76.                                                 if i >= 0 {
  77.                                                         label = label[i+1:]
  78.                                                         //fmt.Println("#" + p[1][:i] + "#")
  79.                                                         if p[1][:i] == "点" {
  80.                                                                 // 若标签如 M_2 之类的,表示带下标的 $M_2$ 格式
  81.                                                                 if strings.Index(label, "_") < 0 {
  82.                                                                         st := fmt.Sprintf(`<text x="%.2f" y="%.2f">%s</text>`, d1, d2, label)
  83.                                                                         parent.SetHtml(st)
  84.                                                                         //fmt.Println(p[1])
  85.                                                                 }
  86.                                                         }
  87.                                                 } else {
  88.                                                                 st := fmt.Sprintf(`<text x="%.2f" y="%.2f">%s</text>`, d1, d2, p[2])
  89.                                                                 parent.SetHtml(st)
  90.                                                 }
  91.                                         }
  92.                                 } else if strings.Index(dstr, "C ") > 0 {
  93.                                         // 将画点的代码改为用 <circle> 指令
  94.                                         reg := regexp.MustCompile(`<title>(.*)</title>.*\n.*<desc>(.*)</desc>`)
  95.                                         p := reg.FindStringSubmatch(str)
  96.                                         if len(p) > 0 {
  97.                                                 label := p[1]
  98.                                                 i := strings.Index(label, " ")
  99.                                                 if i >= 0 {
  100.                                                         label = label[i+1:]
  101.                                                         //fmt.Println("#" + p[1][:i] + "#")
  102.                                                         if p[1][:i] == "点" {
  103.                                                                 if d1 == prevx && d2 == prevy {
  104.                                                                         parent.Get(0).RemoveChild(s.Get(0))
  105.                                                                 } else {       
  106.                                                                         prevx, prevy = d1, d2
  107.                                                                         st := fmt.Sprintf(`<circle cx="%.2f" cy="%.2f" r="5" fill="blue"/> `, d1-3.0, d2)
  108.                                                                         parent.SetHtml(st)
  109.                                                                 }       
  110.                                                         }
  111.                                                 } else {
  112.                                                         //这种情况需要进一步跟踪
  113.                                                         // st := fmt.Sprintf(`<text x="%.2f" y="%.2f">%s</text>`, d1, d2, p[2])
  114.                                                         // parent.SetHtml(st)
  115.                                                 }
  116.                                         }
  117.                                 }
  118.                         }
  119.                 }
  120.         })
  121.         dom.Find(`html`).Each(func(i int, selection *goquery.Selection) {
  122.                 outstr, _ := selection.Html()
  123.                 ioutil.WriteFile(fname, []byte(outstr[19:len(outstr)-29]), 0666)
  124.         })
  125. }
复制代码

手机版|悠闲数学娱乐论坛(第3版)

GMT+8, 2025-3-4 11:59

Powered by Discuz!

× 快速回复 返回顶部 返回列表